home *** CD-ROM | disk | FTP | other *** search
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: Makefile QSO.c alarm.c alarm.h beep.h beepHP.c beepSun.c
- # beepX11.c morse.c
- # Wrapped by joe@montebello on Sat Nov 28 03:13:57 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(1101 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# Select your audio output device. Current choices are:
- X# Sun: Sun workstation with audio hardware.
- X# HP: HP9000s700 with audio hardware.
- X# X11: The X11 window system.
- X# Adding a new device is as simple as creating a new implementation of the
- X# beep.h interface. See beep*.c for examples. Please send any additions
- X# to the authors.
- X#
- XDEVICE = X11
- X
- X# For termio a la System V, add -DUSG to DEFINES.
- X# For alternate random number generator, add either -DUSELRAND for lrand48(),
- X# or -DUSERAND for (ugh) rand().
- XDEFINES =
- X
- X
- XCFLAGS = -O ${DEFINES}
- X
- X
- Xmorse: morse${DEVICE}
- X rm -f $@
- X ln morse${DEVICE} $@
- X
- XmorseSun: morse.o beepSun.o
- X cc -o $@ morse.o beepSun.o -L/usr/demo/SOUND -laudio -lm
- X
- XmorseHP: morse.o beepHP.o alarm.o
- X cc -o $@ morse.o beepHP.o alarm.o -lm
- X
- XmorseX11: morse.o beepX11.o alarm.o
- X cc -o $@ morse.o beepX11.o alarm.o -lX11
- X
- XQSO: QSO.o
- X cc -o $@ QSO.o
- X
- Xtest:
- X QSO | morse -l -e
- X
- Xclean:
- X rm -f *.o morseSun morseHP morseX11 QSO
- X
- Xsqueakyclean: clean
- X rm -f morse
- X
- X
- Xmorse.o: beep.h
- XbeepSun.o: beep.h
- XbeepHP.o: beep.h alarm.h
- XbeepX11.o: beep.h alarm.h
- Xalarm.o: alarm.h
- END_OF_FILE
- if test 1101 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'QSO.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'QSO.c'\"
- else
- echo shar: Extracting \"'QSO.c'\" \(27050 characters\)
- sed "s/^X//" >'QSO.c' <<'END_OF_FILE'
- X/*
- X * Return-Path: <pjd@cadillac.siemens.com>
- X * Received: from cadillac.siemens.com by montebello.soest.hawaii.edu (4.1/montebello-MX-1.9)
- X * id AA01487; Mon, 10 Aug 92 03:21:41 HST
- X * Received: from kevin.siemens.com by cadillac.siemens.com (4.1/SMI-4.0)
- X * id AA25847; Mon, 10 Aug 92 09:21:37 EDT
- X * Date: Mon, 10 Aug 92 09:21:37 EDT
- X * From: pjd@cadillac.siemens.com (paul j. drongowski)
- X * Message-Id: <9208101321.AA25847@cadillac.siemens.com>
- X * To: joe@montebello.soest.hawaii.edu
- X * Status: RO
- X *
- X * This copy is slightly hacked by Joe Dellinger, August 1992
- X * And some more... November 1992
- X */
- X
- X/*
- X * Generate QSO
- X */
- X
- X/*
- X * Author: Paul J. Drongowski / N2OQT
- X * Address: 1 Allen Court
- X * Plainsboro, New Jersey 08536
- X * Date: 10 October 1991
- X *
- X * Copyright (c) 1991 Paul J. Drongowski
- X */
- X
- X/*
- X * When run, this program generates a single QSO. The form of the
- X * QSO is similar to QSO`s one would expect to hear at a code test.
- X * It begins with a series of V's (commented out in this version),
- X * callsigns of the receiver and
- X * sender, followed by a few sentences about weather, name,
- X * occupation, etc. The QSO ends with the callsigns of the receiver
- X * and sender.
- X *
- X * All output is produced using "printf." This should make the
- X * program easy to port. Output can be piped into another program
- X * such as sparc-morse on the Sun or it can be redirected into
- X * a file (without viewing the contents of course!)
- X *
- X * The program design is similar to a "random poetry generator"
- X * or "mad-libs." Each QSO form is generated by its own C function,
- X * such as "PutForm1." Each function calls other C functions to
- X * produce the sentences in the QSO. The sentence forms are
- X * selected somewhat randomly as well as any blanks to be filled.
- X * Words and phrases are selected from several lists such as
- X * "Transceiver," "Antenna," "Job," etc. Sometimes this scheme is
- X * clever as in the formation of city names. Sometimes it is
- X * stupidly simple-minded and grammatical agreement is lost.
- X * By the way, the callsigns are real and were picked from
- X * rec.radio.amateur.misc on USENET.
- X *
- X * The program was constructed in C for Sun workstations. It uses
- X * the library function "drand48" in function "Roll" to produce
- X * pseudo-random numbers. The library function "srand48" and "time"
- X * in "main" are used to set the pseudo-random number seed.
- X *
- X * Known problems and caveats? Hey, it`s software! All Morse
- X * training programs handle the procedural signs (e.g., AR, SK)
- X * differently. The function "PutQSO" currently prints "+ @"
- X * for the AR and SK at the end of the QSO. These may be ignored,
- X * mapped into something else, or just plain cause your training
- X * program to roll over and play dead. I don`t know. This is a
- X * cheap hack.
- X *
- X * And speaking of cheap... The program will not generate all
- X * characters and pro-signs that are found on an "official" code
- X * test. This program is for practice only and should be supplemented
- X * with lots of random code.
- X *
- X * Please note that I retain the copyright
- X * to this program. You may use it for any non-commercial purposes.
- X * This is roughly equivalent to "fair use."
- X *
- X * Always have fun!
- X */
- X
- X
- X#include <sys/types.h>
- X#include <sys/time.h>
- X
- Xint NXCVR ;
- Xchar *Transceiver[] =
- X
- X {
- X "Collins 75S=3",
- X "Collins KWM=2",
- X "Drake TR3",
- X "Drake TR4",
- X "Drake T=4XB",
- X "Eico 753",
- X "Hallicrafters SR150",
- X "Hallicrafters SR160",
- X "Hallicrafters SR400",
- X "Hallicrafters SR500",
- X "Hallicrafters SR2000",
- X "Heathkit DX=660B",
- X "Heathkit HG=10B",
- X "Heathkit HR=10",
- X "Heathkit HW12",
- X "Heathkit HW22",
- X "Heathkit HW32",
- X "Heathkit HW12A",
- X "Heathkit HW22A",
- X "Heathkit HW32A",
- X "Heathkit HW100",
- X "Heathkit SB100",
- X "Icom IC=275",
- X "Icom IC=475",
- X "Icom IC=575",
- X "Icom IC=725",
- X "Icom IC=726",
- X "Icom IC=730",
- X "Icom IC=735",
- X "Icom IC=751",
- X "Icom IC=765",
- X "Icom IC=781",
- X "Icom IC=1275",
- X "Kenwood TS=77",
- X "Kenwood TS=140",
- X "Kenwood TS=440",
- X "Kenwood TS=680",
- X "Kenwood TS=711",
- X "Kenwood TS=850",
- X "Kenwood TR=450",
- X "Kenwood TR=751",
- X "Kenwood TR=850",
- X "Kenwood TR=851",
- X "National NCX3",
- X "National NCX5",
- X "National NCL 200",
- X "Radio Shack HTX=100",
- X "RS HTX=100",
- X "Swan 120",
- X "Swan 140",
- X "Swan 180",
- X "Swan 240",
- X "Swan 350",
- X "Ten Tec 585",
- X "Ten Tec 562",
- X "Ten Tec Delta",
- X "Ten Tec Argonaut",
- X "Ten Tec Omni",
- X "Yaesu FT=101",
- X "Yaesu FT=736",
- X "Yaesu FT=747",
- X "Yaesu FT=757",
- X "Yaesu FT=767",
- X "Yaesu FT=990",
- X "Yaesu FT=1000",
- X "Homebrew",
- X 0
- X } ;
- X
- Xint NANTENNA ;
- Xchar *Antenna[] =
- X
- X {
- X "beam",
- X "delta loop",
- X "dipole",
- X "doublet zepp",
- X "half wave dipole",
- X "inverted V",
- X "whip",
- X "delta loop",
- X "parasitic beam",
- X "log periodic",
- X "quad loop",
- X "quad vertical",
- X "quagi",
- X "quarter wave vertical",
- X "rhombic",
- X "long=wire",
- X "ground=plane",
- X "trap doublet",
- X "yagi",
- X "zepp",
- X "monobander",
- X "tribander",
- X "symmetrical delta loop",
- X "3 element beam",
- X "5 band vertical",
- X "5 element loop",
- X "10 meter dipole",
- X "10 meter whip",
- X "7 band beam",
- X 0
- X } ;
- X
- Xint NUPFEET ;
- Xchar *UpFeet[] =
- X
- X {
- X "10", "15", "20", "25", "30", "35", "40", "45",
- X "50", "55", "60", "65", "70", "75", "80", "85",
- X "90", "95", "100",
- X 0
- X } ;
- X
- Xint NWX1 ;
- Xchar *Weather1[] =
- X
- X {
- X "sunny",
- X "rain",
- X "freezing rain",
- X "sleet",
- X "snow",
- X "cloudy",
- X "partly cloudy",
- X "partly sunny",
- X "clear",
- X 0
- X } ;
- X
- Xint NWX2 ;
- Xchar *Weather2[] =
- X
- X {
- X "cold and windy",
- X "raining",
- X "snowing",
- X "sunny",
- X "hot",
- X "windy and warm",
- X "cloudy",
- X "drizzling",
- X "foggy",
- X "wet/foggy",
- X "fog/drizzle",
- X "hot/muggy",
- X "hot/dry",
- X "cool/windy",
- X "smoggy",
- X "hot/smoggy",
- X "cold/dry",
- X "hot/humid",
- X "warm",
- X "windy",
- X "very hot",
- X "very cold",
- X "very windy",
- X "wet",
- X "wet/windy",
- X "humid",
- X "hot and humid",
- X 0
- X } ;
- X
- Xint NPOWER ;
- Xchar *Power[] =
- X
- X {
- X "5", "10", "20", "25", "40", "50", "80", "100",
- X "125", "140", "150", "170", "200", "250", "270", "300",
- X 0
- X } ;
- X
- Xint NJOB ;
- Xchar *Job[] =
- X
- X {
- X "engineer",
- X "nurse",
- X "fireman",
- X "mechanic",
- X "programmer",
- X "carpenter",
- X "electrician",
- X "writer",
- X "teacher",
- X "doctor",
- X "attorney",
- X "lawyer",
- X "clerk",
- X "chemist",
- X "librarian",
- X "teller",
- X "physician",
- X "physicist",
- X "chemist",
- X "mathematician",
- X "professor",
- X "driver",
- X "milkman",
- X "gardener",
- X "bricklayer",
- X "guard",
- X "dentist",
- X "curator",
- X "farmer",
- X "stock broker",
- X "letter carrier",
- X "designer",
- X "student",
- X "college student",
- X "high school student",
- X "administrator",
- X "police officer",
- X "investment banker",
- X "politician",
- X 0
- X } ;
- X
- Xint NNAME ;
- Xchar *Name[] =
- X
- X {
- X "Al",
- X "Alan",
- X "Alice",
- X "Allen",
- X "Alex",
- X "Alexeev",
- X "Amber",
- X "Anne",
- X "Art",
- X "Barbara",
- X "Bart",
- X "Betty",
- X "Bea",
- X "Bill",
- X "Bob",
- X "Bruce",
- X "Bud",
- X "Carl",
- X "Carol",
- X "Cathy",
- X "Cheryl",
- X "Chris",
- X "Christy",
- X "Chuck",
- X "Dale",
- X "Dave",
- X "David",
- X "Dennis",
- X "Diane",
- X "Dick",
- X "Dan",
- X "Don",
- X "Ed",
- X "Elaine",
- X "Ellen",
- X "Francie",
- X "Fred",
- X "Gary",
- X "Helen",
- X "Ingrid",
- X "Frank",
- X "George",
- X "Gilda",
- X "Gus",
- X "Harry",
- X "Henry",
- X "Jack",
- X "James",
- X "Jane",
- X "Janet",
- X "Jeff",
- X "Jessica",
- X "Jill",
- X "Jim",
- X "Joan",
- X "Joe",
- X "John",
- X "Jon",
- X "Kathy",
- X "Kevin",
- X "Karen",
- X "Karl",
- X "Keith",
- X "Ken",
- X "Kent",
- X "Kristen",
- X "Kurt",
- X "Larry",
- X "Lauren",
- X "Liholiho",
- X "Linda",
- X "Lou",
- X "Lynda",
- X "Lynn",
- X "Marc",
- X "Margaret",
- X "Marv",
- X "Maria",
- X "Mark",
- X "Marty",
- X "Mary",
- X "Mike",
- X "Monica",
- X "Nancy",
- X "Neil",
- X "Noelani",
- X "Oliver",
- X "Olivia",
- X "Pat",
- X "Patrick",
- X "Paul",
- X "Paula",
- X "Peter",
- X "Phil",
- X "Ralph",
- X "Ray",
- X "Rex",
- X "Rich",
- X "Rick",
- X "Roy",
- X "Ron",
- X "Sally",
- X "Sam",
- X "Scott",
- X "Scottie",
- X "Spencer",
- X "Steve",
- X "Stu",
- X "Sue",
- X "Terry",
- X "Tim",
- X "Todd",
- X "Tom",
- X "Tony",
- X "Thomas",
- X "Walt",
- X "Wendy",
- X "William",
- X "Zelda",
- X 0
- X } ;
- X
- Xint NCALLSIGN ;
- Xchar *Sender, *Receiver ;
- Xchar *CallSign[] =
- X
- X {
- X "AA0ET",
- X "AA4LR",
- X "AA5BT",
- X "AA6NP",
- X "AA6YD",
- X "AA9BK",
- X "AB5AP",
- X "AB6FI",
- X "AC4HF",
- X "G0GWA",
- X "GM4ZNX",
- X "KA0WCH",
- X "KA1AXY",
- X "KA1CV",
- X "KA1UTU",
- X "KA1ZGC",
- X "KA6S",
- X "KA2RAF",
- X "KB0CY",
- X "KB2NRH",
- X "KB6CSP",
- X "KB6JXT",
- X "KC6SKV",
- X "KC6SSS",
- X "KC6TDR",
- X "KC6VWV",
- X "KD3FU",
- X "KD4AUS",
- X "KD4CPL",
- X "KE2TP",
- X "KE4ZV",
- X "KF8NH",
- X "KF6BZF",
- X "KJ6NN",
- X "KJ9U",
- X "KK6JQ",
- X "KM3T",
- X "KT7H",
- X "K2WK",
- X "K5RC",
- X "K6XO",
- X "K6OCK",
- X "K9ALD",
- X "IK5AAX",
- X "I5FLN",
- X "JA1BLV",
- X "N1AL",
- X "N1JCX",
- X "N4PBK",
- X "N4VRN",
- X "N5IAL",
- X "N5OP",
- X "N6BIS",
- X "N6MWC",
- X "N6TTO",
- X "N8EMR",
- X "N9MYI",
- X "N9FZX",
- X "N9JRV",
- X "N9LFF",
- X "NE3X",
- X "NH6ZW",
- X "NJ7E",
- X "NR3Z",
- X "NT1G",
- X "OD5NG",
- X "OH3BK",
- X "OH8NUP",
- X "TG9VT",
- X "UT5RP",
- X "VE6MGS",
- X "VE7EMD",
- X "VK2BQS",
- X "VK2EG",
- X "W0PBV",
- X "W0RIJ",
- X "W0RSB",
- X "WA1UXA",
- X "WA2AGE",
- X "WA3EEC",
- X "WA3TBL",
- X "WA3UQV",
- X "WA5RPF",
- X "WA6DGX",
- X "WA7VYJ",
- X "WA8ZGO",
- X "WB4JCM",
- X "WB5FDP",
- X "WB5FKH",
- X "WB5NRN",
- X "WB2CJL",
- X "WB7CJO",
- X "WB7EEL",
- X "WB7TZA",
- X "WB8EOH",
- X "WB9IVR",
- X "WD0EIB",
- X "WX9T",
- X "W2FG",
- X "W2JGR",
- X "W3GRG",
- X "W3OTC",
- X 0
- X } ;
- X
- Xint NLICENSE ;
- Xchar *License[] =
- X
- X {
- X "Novice",
- X "Technician",
- X "Tech",
- X "General",
- X "Advanced",
- X "Extra",
- X 0
- X } ;
- X
- Xint NCITY ;
- Xchar *City[] =
- X
- X {
- X "Aiea",
- X "Alexander",
- X "Asbury",
- X "Baker",
- X "Beckley",
- X "Bedford",
- X "Brunswick",
- X "Burnsville",
- X "Clarksville",
- X "Cambridge",
- X "Charleston",
- X "Circleville",
- X "Clarksburg",
- X "Clear Lake",
- X "Cleveland",
- X "Crystal",
- X "Duncanville",
- X "Elizabeth",
- X "Ewa",
- X "Fairbanks",
- X "Fairfield",
- X "Flint",
- X "Gahanna",
- X "Grant",
- X "Greensburg",
- X "Harper",
- X "Honolulu",
- X "Hillsdale",
- X "Jamestown",
- X "Jefferson",
- X "Kaaawa",
- X "Kona",
- X "Lawrenceville",
- X "Lakewood",
- X "Lincoln",
- X "Litchfield",
- X "London",
- X "Long Branch",
- X "Lyndhurst",
- X "Lyndale",
- X "Lynnville",
- X "Mansfield",
- X "Maple",
- X "Meadows",
- X "Mentor",
- X "Mercer",
- X "Mesquite",
- X "Midland",
- X "Milldale",
- X "Milltown",
- X "Moorestown",
- X "Mountain View",
- X "Murray",
- X "Newfield",
- X "Newport",
- X "New London",
- X "Olmstead",
- X "Oak",
- X "Oxnard",
- X "Oxford",
- X "Paradise",
- X "Paris",
- X "Perry",
- X "Potter",
- X "Pottsville",
- X "Redwood",
- X "Russellville",
- X "Salem",
- X "Sandy",
- X "Saratoga",
- X "Smithville",
- X "Springdale",
- X "Springfield",
- X "Starkville",
- X "Sunnyvale",
- X "Tinker",
- X "Trenton",
- X "Walnut",
- X "Warren",
- X "Warsaw",
- X "Washington",
- X "Weston",
- X "Wheatfield",
- X "Williamson",
- X "Worchester",
- X "Zolton",
- X 0
- X } ;
- X
- Xint NNEWCITY ;
- Xchar *NewCity[] =
- X
- X {
- X "Albany",
- X "Avalon",
- X "Barnard",
- X "Brunswick",
- X "Bedford",
- X "Chester",
- X "Conway",
- X "Dime Box",
- X "Franklin",
- X "Granville",
- X "Hamilton",
- X "Morris",
- X "Oxford",
- X "Salisbury",
- X "Stafford",
- X "Stanton",
- X "Trenton",
- X "Troy",
- X "Walpole",
- X "Warren",
- X "Wilton",
- X "Weston",
- X "Windsor",
- X "Zulch",
- X 0
- X } ;
- X
- Xint NCITYHTS ;
- Xchar *CityHeights[] =
- X
- X {
- X "Apple",
- X "Ashford",
- X "Baker",
- X "Baldwin",
- X "Banner",
- X "Barnard",
- X "Benton",
- X "Carson",
- X "Chester",
- X "Conway",
- X "Cornwall",
- X "Crystal",
- X "Fletcher",
- X "Franklin",
- X "Granite",
- X "Grant",
- X "Harper",
- X "Jefferson",
- X "Hamilton",
- X "Hickory",
- X "Lincoln",
- X "Maple",
- X "Mercer",
- X "Morgan",
- X "Morris",
- X "Murray",
- X "Oak",
- X "Orwell",
- X "Quail",
- X "Perry",
- X "Potter",
- X "Salem",
- X "Stafford",
- X "Stone",
- X "Tinker",
- X "Walnut",
- X "Warren",
- X "Washington",
- X "Weston",
- X "Wilton",
- X 0
- X } ;
- X
- Xint NNEW ;
- Xchar *New[] =
- X
- X {
- X "New",
- X "Old",
- X "North",
- X "South",
- X "East",
- X "West",
- X 0
- X } ;
- X
- Xint NHEIGHTS ;
- Xchar *Heights[] =
- X
- X {
- X "Castle",
- X "Heights",
- X "Island",
- X "Valley",
- X "City",
- X "Creek",
- X "Park",
- X "Mill",
- X "Neck",
- X 0
- X } ;
- X
- Xint NSTATE ;
- Xchar *State[] =
- X
- X {
- X "Alabama",
- X "Alaska",
- X "Arizona",
- X "Arkansas",
- X "California",
- X "Colorado",
- X "Connecticut",
- X "Delaware",
- X "Florida",
- X "Gaum",
- X "Georgia",
- X "Hawaii",
- X "Idaho",
- X "Illinois",
- X "Indiana",
- X "Iowa",
- X "Kansas",
- X "Kentucky",
- X "Louisiana",
- X "Maine",
- X "Maryland",
- X "Massachusetts",
- X "Michigan",
- X "Midway",
- X "Minnesota",
- X "Mississippi",
- X "Missouri",
- X "Montana",
- X "Nebraska",
- X "Nevada",
- X "New Hampshire",
- X "New Jersey",
- X "New Mexico",
- X "New York",
- X "North Carolina",
- X "North Dakota",
- X "Ohio",
- X "Oklahoma",
- X "Oregon",
- X "Pennsylvania",
- X "Puerto Rico",
- X "Rhode Island",
- X "Saipan",
- X "American Samoa",
- X "South Carolina",
- X "South Dakota",
- X "Tennessee",
- X "Texas",
- X "Utah",
- X "Vermont",
- X "Virginia",
- X "Virgin Islands",
- X "Wake Island",
- X "Washington",
- X "West Virginia",
- X "Wisconsin",
- X "Wyoming",
- X 0
- X } ;
- X
- Xint NMISC ;
- Xchar *Miscellaneous[] =
- X {
- X "I sometimes work packet on vhf.",
- X "I sometimes work packet on vhf.",
- X "We are on vacation and I am mobile.",
- X "We are on vacation and I am mobile.",
- X "Your signal is chirpy.",
- X "Lots of QRM.",
- X "Lots of QRM.",
- X "Should we QSY?",
- X "Please QRS.",
- X "Please QRS.",
- X "Tnx for the report.",
- X "Thanks for the call.",
- X "Tnx for the call.",
- X "Tnx for ur call.",
- X "QRM",
- X "QRM?",
- X "QRS",
- X "QRS?",
- X "QSY?",
- X "QSK?",
- X "QRX?",
- X "QTH?",
- X "QTR?",
- X "What is your QTH?",
- X "Is it green there or brown?",
- X "Where do you live?",
- X "Where do you live?",
- X "Where do you live now?",
- X "How long have you been a radio amateur?",
- X "How long have you been a radio amateur?",
- X "What are your hobbies?",
- X "What is your hobby?",
- X "Must QRT for dinner.",
- X "Must QRT for dinner.",
- X "Must QRT for hot dinner.",
- X "Must QRT for cold dinner.",
- X "Must QRT for lunch.",
- X "Must QRT for lunch.",
- X "Must QRT for hot lunch.",
- X "Must QRT for sleep.",
- X "Must QRT for some sleep.",
- X "Must QRT for bathroom break.",
- X "Must QRT, lightning threatens.",
- X "Must QRT, lightning storm has started.",
- X "Must QRT, tornado sirens sounding.",
- X "Must QRT, tsunami sirens sounding.",
- X "Must QRT to hear news about approaching hurricane.",
- X "Must QRT, weather radio warbling.",
- X "Must QRT invading tanks making too much noise outside to hear you.",
- X "Must QRT occupation forces knocking at door.",
- X "I am mobile and am going to the office.",
- X "I am mobile and am going to work.",
- X "I am mobile and driving to work.",
- X "I am mobile, driving home from work.",
- X "I am mobile, stuck in traffic.",
- X "I am mobile, driving cross country.",
- X "I am mobile, riding a Peruvian Paso Fino horse.",
- X "Ive fallen and I cant get up.",
- X "How is my signal?",
- X "Hows my signal?",
- X "How copy so far?",
- X "How copy so far?",
- X "How copy?",
- X "Copy?",
- X "Copy?",
- X "Cpy?",
- X "Do you understand English?",
- X "Do u understand English?",
- X "Habla espanol?",
- X "Sprechen Sie Deutsch?",
- X "What is your job?",
- X "Whats your job?",
- X "How is the weather?",
- X "Hows the weather?",
- X "How is the weather?",
- X "Are you using a linear amplifier?",
- X "ru using linear amplifier?",
- X "I am using a linear amplifier.",
- X "am using a linear amplifier.",
- X "Are you using a linear amplifier?",
- X "You are using a nonlinear amplifier?",
- X "Propagation is good.",
- X "Propagation is good.",
- X "Propagation is very good.",
- X "Propagation is poor.",
- X "Propagation is very poor.",
- X "Are you on daylight savings time?",
- X "Did you hear the news?",
- X "Did you hear news?",
- X "Is the bad news true?",
- X "Sorry, stack of books just fell over.",
- X "There is an eclipse of the moon right now.",
- X "Do you recycle often?",
- X "Do you prefer metric units?",
- X "We just felt a small quake here.",
- X "Whoa, we are having an earthquake here. A real roller.",
- X "You are my first contact today.",
- X "You are my second contact today.",
- X "You are my last contact today.",
- X "Are you married?",
- X "Do you have a horse?",
- X "Do you have a dog?",
- X "Do you have a cat?",
- X "Do you have a ferret?",
- X "Do you have a gecko?",
- X "A clumsy gecko just fell on my hand.",
- X "How old is your rig?",
- X "How did you learn morse code?",
- X "Do you know morse code?",
- X "When did you start to learn morse code?",
- X "Are you good at calculus? I have a question for you.",
- X "Are you good at group theory? I have a question for you.",
- X "Can you pick master locks? Those are supposed to be easy.",
- X "Can you pick kryptonite locks?",
- X "QLF?",
- X "There is a rainbow outside the window.",
- X "I just saw a bolide.",
- X "Do you know the word copacetic?",
- X "Do you know the word garralous?",
- X "What time zone are you in?",
- X "Would you have given Morse a Nobel prize?",
- X "Our neighbors have a horse named morse.",
- X "What is your elevation?",
- X "What is the air pressure there?",
- X "I sometimes monitor ulf for earthquake precursors.",
- X "Can you think of something else interesting to say?",
- X "+@=x/,? 73 just testing you.",
- X "@w=+/,? 73 just testing you.",
- X ",?/=+9@ 73 just testing you.",
- X ",?/=q+@ 73 just testing u.",
- X 0
- X };
- X
- Xint NRST ;
- Xchar *RST[] =
- X
- X {
- X "555",
- X "577",
- X "578",
- X "579",
- X "588",
- X "589",
- X "599",
- X "478",
- X "354",
- X "248",
- X "126",
- X 0
- X } ;
- X
- X/*
- X ********************
- X * Utility routines *
- X ********************
- X */
- X
- Xint CountStrings(StringVector) char *StringVector[] ;
- X
- X /*
- X * Count the number of string values in the supplied vector
- X * of pointers. Start with the first pointer and stop when
- X * NIL (0) is encountered.
- X */
- X
- X {
- X register char **SV ;
- X register int Count ;
- X
- X Count = 0 ;
- X
- X for (SV = StringVector ; *SV ; SV++)
- X {
- X Count++ ;
- X }
- X return(Count) ;
- X }
- X
- Xint Roll(Number) int Number ;
- X
- X {
- X double drand48() ;
- X return( (int)(drand48() * (Number/*-1*/)) ) ;
- X }
- X
- Xchar *Choose(Words, Number) char *Words[] ; int Number ;
- X
- X {
- X return( Words[ Roll(Number) ] ) ;
- X }
- X
- X/*
- X *************************************
- X * Routines to put sentences/clauses *
- X *************************************
- X */
- X
- Xvoid PutMisc()
- X
- X {
- X printf("%s\n", Choose(Miscellaneous, NMISC)) ;
- X }
- X
- Xvoid PutThanks()
- X
- X {
- X switch(Roll(6))
- X {
- X case 0:
- X printf("Thanks for your call.\n") ;
- X break ;
- X case 1:
- X printf("Tnx for ur call.\n") ;
- X break ;
- X case 2:
- X printf("Tnx for the call.\n") ;
- X break ;
- X case 3:
- X printf("Thanks for the call.\n") ;
- X break ;
- X default:
- X printf("Thanks %s for the call.\n", Choose(Name, NNAME)) ;
- X break ;
- X }
- X }
- X
- Xvoid PutName()
- X
- X {
- X switch (Roll(4))
- X {
- X case 0:
- X printf("Name is %s.\n", Choose(Name, NNAME)) ;
- X break ;
- X case 1:
- X printf("This is %s.\n", Choose(Name, NNAME)) ;
- X break ;
- X case 2:
- X printf("%s here.\n", Choose(Name, NNAME)) ;
- X break ;
- X default:
- X printf("My name is %s.\n", Choose(Name, NNAME)) ;
- X break ;
- X }
- X }
- X
- Xvoid PutJob()
- X
- X {
- X switch(Roll(10))
- X {
- X case 0:
- X case 1:
- X printf("Occupation is %s.\n", Choose(Job, NJOB)) ;
- X break ;
- X case 2:
- X case 3:
- X printf("My occupation is %s.\n", Choose(Job, NJOB)) ;
- X break ;
- X case 4:
- X case 5:
- X printf("I work as a %s.\n", Choose(Job, NJOB)) ;
- X break ;
- X case 6:
- X printf("I was a %s, now unemployed.\n", Choose(Job, NJOB)) ;
- X break ;
- X default:
- X printf("I am a %s.\n", Choose(Job, NJOB)) ;
- X break ;
- X }
- X }
- X
- Xvoid PutAge()
- X
- X {
- X switch(Roll(3))
- X {
- X case 0:
- X printf("I am %d years old.\n", Roll(60)+16) ;
- X break ;
- X case 1:
- X printf("My age is %d.\n", Roll(60)+16) ;
- X break ;
- X default:
- X printf("Age is %d.\n", Roll(60)+16) ;
- X break ;
- X }
- X }
- X
- Xvoid PutLicense()
- X
- X {
- X switch(Roll(4))
- X {
- X case 0:
- X printf("I have a %s class license.\n", Choose(License, NLICENSE)) ;
- X break ;
- X case 1:
- X printf("I am a %s class ham.\n", Choose(License, NLICENSE)) ;
- X break ;
- X case 2:
- X printf("I have been licensed %d years as %s class.\n",
- X Roll(20)+1, Choose(License, NLICENSE)) ;
- X break ;
- X default:
- X printf("I have been a %s class ham for %d years.\n",
- X Choose(License, NLICENSE), Roll(20)+1) ;
- X break ;
- X }
- X }
- X
- Xvoid PutTemperature()
- X
- X {
- X printf("Temperature is %d.\n", Roll(80) + 10) ;
- X }
- X
- Xvoid PutWeather1()
- X
- X {
- X switch (Roll(14))
- X {
- X case 0:
- X printf("Weather here is %s.\n", Choose(Weather1, NWX1)) ;
- X PutTemperature() ;
- X break ;
- X case 1:
- X printf("Weather is %s.\n", Choose(Weather1, NWX1)) ;
- X PutTemperature() ;
- X break ;
- X case 2:
- X printf("WX is %s.\n", Choose(Weather1, NWX1)) ;
- X PutTemperature() ;
- X break ;
- X case 3:
- X printf("Weather here is %s.\n", Choose(Weather1, NWX1)) ;
- X break ;
- X case 4:
- X printf("Weather is %s.\n", Choose(Weather1, NWX1)) ;
- X break ;
- X case 5:
- X printf("WX is %s.\n", Choose(Weather1, NWX1)) ;
- X break ;
- X case 6:
- X PutTemperature() ;
- X printf("Weather here is %s.\n", Choose(Weather1, NWX1)) ;
- X break ;
- X case 7:
- X PutTemperature() ;
- X printf("Weather is %s.\n", Choose(Weather1, NWX1)) ;
- X break ;
- X case 8:
- X PutTemperature() ;
- X printf("WX is %s.\n", Choose(Weather1, NWX1)) ;
- X break ;
- X case 9:
- X printf("Weather here is %s and temperature is %d.\n",
- X Choose(Weather1, NWX1), Roll(80)+10) ;
- X break ;
- X case 10:
- X printf("Weather is %s, temperature %d.\n",
- X Choose(Weather1, NWX1), Roll(80)+10) ;
- X break ;
- X case 11:
- X printf("WX is %d degrees and %s.\n",
- X Roll(80)+10, Choose(Weather1, NWX1));
- X break ;
- X case 12:
- X printf("The WX is %s and the temp is %d degrees.\n",
- X Choose(Weather1, NWX1), Roll(80)+10) ;
- X break ;
- X default:
- X printf("WX is %s and %d degrees.\n",
- X Choose(Weather1, NWX1), Roll(80)+10);
- X }
- X }
- X
- Xvoid PutWeather2()
- X
- X {
- X switch(Roll(5))
- X {
- X case 0:
- X printf("It is %s.\n", Choose(Weather2, NWX2));
- X break ;
- X case 1:
- X printf("It is %s and %d degrees.\n",
- X Choose(Weather2, NWX2), Roll(80)+10) ;
- X break ;
- X case 2:
- X printf("The WX is %s and the temp is %d degrees.\n",
- X Choose(Weather2, NWX2), Roll(80)+10) ;
- X break ;
- X case 3:
- X printf("WX is %s and the temp is %d degrees.\n",
- X Choose(Weather2, NWX2), Roll(80)+10) ;
- X break ;
- X default:
- X printf("It is %s here.\n", Choose(Weather2, NWX2));
- X break ;
- X }
- X }
- X
- Xvoid PutWeather()
- X
- X {
- X switch (Roll(2))
- X {
- X case 0:
- X PutWeather1() ;
- X break ;
- X default:
- X PutWeather2() ;
- X break ;
- X }
- X }
- X
- Xvoid PutCityState()
- X
- X {
- X switch(Roll(4))
- X {
- X case 0:
- X printf("%s %s, ", Choose(New, NNEW), Choose(NewCity, NNEWCITY)) ;
- X break ;
- X case 1:
- X printf("%s %s, ",
- X Choose(CityHeights, NCITYHTS), Choose(Heights,NHEIGHTS)) ;
- X break ;
- X default:
- X printf("%s, ", Choose(City, NCITY)) ;
- X break ;
- X }
- X printf("%s.\n", Choose(State, NSTATE)) ;
- X }
- X
- Xvoid PutLocation()
- X
- X {
- X switch(Roll(3))
- X {
- X case 0:
- X printf("My location is ");
- X break ;
- X case 1:
- X printf("My QTH is ") ;
- X break ;
- X default:
- X printf("QTH is ") ;
- X break ;
- X }
- X PutCityState() ;
- X }
- X
- Xvoid PutRig()
- X
- X {
- X switch(Roll(5))
- X {
- X case 0:
- X printf("My rig runs %s watts into a %s up %s feet.\n",
- X Choose(Power, NPOWER), Choose(Antenna, NANTENNA),
- X Choose(UpFeet, NUPFEET)) ;
- X break ;
- X case 1:
- X printf("Rig is a %s watt %s and antenna is a %s.\n",
- X Choose(Power, NPOWER), Choose(Transceiver, NXCVR),
- X Choose(Antenna, NANTENNA)) ;
- X break ;
- X case 2:
- X printf("My transceiver is a %s.\n", Choose(Transceiver, NXCVR)) ;
- X printf("It runs %s watts into a %s.\n",
- X Choose(Power, NPOWER), Choose(Antenna, NANTENNA)) ;
- X break ;
- X case 3:
- X printf("The rig is a %s running %s watts.\n",
- X Choose(Transceiver, NXCVR), Choose(Power, NPOWER)) ;
- X printf("Antenna is a %s up %s feet.\n",
- X Choose(Antenna, NANTENNA), Choose(UpFeet, NUPFEET)) ;
- X break ;
- X default:
- X printf("Rig is a %s running %s watts into a %s up %s feet.\n",
- X Choose(Transceiver, NXCVR), Choose(Power, NPOWER),
- X Choose(Antenna, NANTENNA), Choose(UpFeet, NUPFEET)) ;
- X break ;
- X }
- X }
- X
- Xvoid PutRST()
- X
- X {
- X register char *TheRST ;
- X
- X TheRST = Choose(RST, NRST) ;
- X
- X switch(Roll(8))
- X {
- X case 0:
- X printf("UR RST %s=%s.\n", TheRST, TheRST) ;
- X break ;
- X case 1:
- X printf("RST is %s=%s.\n", TheRST, TheRST) ;
- X break ;
- X case 2:
- X printf("RST %s=%s.\n", TheRST, TheRST) ;
- X break ;
- X case 3:
- X printf("Your RST %s=%s.\n", TheRST, TheRST) ;
- X break ;
- X case 4:
- X printf("Your RST is %s=%s.\n", TheRST, TheRST) ;
- X break ;
- X case 5:
- X printf("Your signal is RST %s/%s.\n", TheRST, TheRST) ;
- X break ;
- X case 6:
- X printf("UR signal is RST %s,%s.\n", TheRST, TheRST) ;
- X break ;
- X default:
- X printf("Your RST is %s/%s.\n", TheRST, TheRST) ;
- X break ;
- X }
- X }
- X
- Xvoid PutFirstCallsign()
- X
- X {
- X Sender = Choose(CallSign, NCALLSIGN) ;
- X Receiver = Choose(CallSign, NCALLSIGN) ;
- X printf("%s de %s\n", Receiver, Sender) ;
- X }
- X
- Xvoid PutLastCallsign()
- X
- X {
- X printf("%s de %s\n", Receiver, Sender) ;
- X }
- X
- Xvoid PutForm0()
- X
- X {
- X PutRST() ;
- X PutName() ;
- X PutLocation() ;
- X PutMisc() ;
- X PutRig() ;
- X PutWeather() ;
- X PutJob() ;
- X PutAge() ;
- X PutMisc() ;
- X PutLicense() ;
- X }
- X
- Xvoid PutForm1()
- X
- X {
- X PutLocation() ;
- X PutRST() ;
- X PutRig() ;
- X PutWeather() ;
- X PutMisc() ;
- X PutName() ;
- X PutLicense() ;
- X PutMisc() ;
- X PutAge() ;
- X PutJob() ;
- X }
- X
- Xvoid PutForm2()
- X
- X {
- X PutThanks() ;
- X PutRST() ;
- X PutName() ;
- X PutWeather() ;
- X PutLocation() ;
- X PutJob() ;
- X PutLicense() ;
- X PutRig() ;
- X PutAge() ;
- X }
- X
- Xvoid PutForm3()
- X
- X {
- X PutLocation() ;
- X PutRST() ;
- X PutRig() ;
- X PutMisc() ;
- X PutName() ;
- X PutMisc() ;
- X PutAge() ;
- X PutJob() ;
- X PutLicense() ;
- X PutMisc() ;
- X PutWeather() ;
- X PutMisc() ;
- X }
- X
- Xvoid PutForm4()
- X
- X {
- X PutThanks() ;
- X PutRST() ;
- X PutJob() ;
- X PutMisc() ;
- X PutMisc() ;
- X PutName() ;
- X PutAge() ;
- X PutLicense() ;
- X PutRig() ;
- X PutLocation() ;
- X PutWeather() ;
- X PutMisc() ;
- X }
- X
- Xvoid PutForm5()
- X
- X {
- X PutLocation() ;
- X PutRST() ;
- X PutRig() ;
- X PutName() ;
- X PutJob() ;
- X PutAge() ;
- X PutMisc() ;
- X PutLicense() ;
- X PutWeather() ;
- X PutMisc() ;
- X }
- X
- XPutQSO()
- X
- X {
- X/* printf("VVV VVV\n") ; */
- X PutFirstCallsign() ;
- X switch(Roll(6))
- X {
- X case 0: PutForm0() ; break ;
- X case 1: PutForm1() ; break ;
- X case 2: PutForm2() ; break ;
- X case 3: PutForm3() ; break ;
- X case 4: PutForm4() ; break ;
- X default: PutForm5() ; break ;
- X }
- X printf("+ @\n") ;
- X PutLastCallsign() ;
- X printf("\n") ;
- X }
- X
- Xmain()
- X
- X {
- X int i ;
- X
- X NXCVR = CountStrings(Transceiver) ;
- X NANTENNA = CountStrings(Antenna) ;
- X NUPFEET = CountStrings(UpFeet) ;
- X NPOWER = CountStrings(Power) ;
- X NRST = CountStrings(RST) ;
- X NWX1 = CountStrings(Weather1) ;
- X NWX2 = CountStrings(Weather2) ;
- X NJOB = CountStrings(Job) ;
- X NNAME = CountStrings(Name) ;
- X NSTATE = CountStrings(State) ;
- X NCITY = CountStrings(City) ;
- X NCITYHTS = CountStrings(CityHeights) ;
- X NNEW = CountStrings(New) ;
- X NHEIGHTS = CountStrings(Heights) ;
- X NNEWCITY = CountStrings(NewCity) ;
- X NLICENSE = CountStrings(License) ;
- X NMISC = CountStrings(Miscellaneous) ;
- X NCALLSIGN = CountStrings(CallSign) ;
- X
- X srand48((long) time(0)) ;
- X
- X PutQSO() ;
- X }
- END_OF_FILE
- if test 27050 -ne `wc -c <'QSO.c'`; then
- echo shar: \"'QSO.c'\" unpacked with wrong size!
- fi
- # end of 'QSO.c'
- fi
- if test -f 'alarm.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'alarm.c'\"
- else
- echo shar: Extracting \"'alarm.c'\" \(1440 characters\)
- sed "s/^X//" >'alarm.c' <<'END_OF_FILE'
- X/* alarm.c -- seligman 6/92 */
- X
- X/*
- X-- Implementation of alarm.h
- X*/
- X
- X#include <signal.h>
- X#include <sys/time.h>
- X
- X
- Xstatic int alarmPending = 0; /* Nonzero when the alarm is set. */
- X
- Xstatic void ualarm();
- Xstatic void AlarmHandler();
- X
- X
- Xvoid AlarmSet(time)
- X int time;
- X{
- X alarmPending = 1;
- X signal(SIGALRM, AlarmHandler);
- X ualarm(1000 * time, 0);
- X}
- X
- X
- X/*
- X-- If an alarm signal is lurking (due to a prior call to SetAlarm), then
- X-- pause until it arrives. This procedure could have simply been written:
- X-- if (alarmPending) pause();
- X-- but that allows a potential race condition.
- X*/
- Xvoid AlarmWait()
- X{
- X long savemask = sigblock(sigmask(SIGALRM));
- X if (alarmPending)
- X sigpause(savemask);
- X sigsetmask(savemask);
- X}
- X
- X
- Xstatic void ualarm(us)
- X unsigned us;
- X{
- X struct itimerval rttimer, old_rttimer;
- X
- X rttimer.it_value.tv_sec = us / 1000000;
- X rttimer.it_value.tv_usec = us % 1000000;
- X rttimer.it_interval.tv_sec = 0;
- X rttimer.it_interval.tv_usec = 0;
- X if (setitimer(ITIMER_REAL, &rttimer, &old_rttimer)) {
- X perror("ualarm");
- X exit(1);
- X }
- X}
- X
- X
- X#ifdef __hpux
- X
- Xstatic void AlarmHandler(sig, code, scp)
- X int sig;
- X int code;
- X struct sigcontext *scp;
- X{
- X alarmPending = 0;
- X /* Prevent alarm signal from interrupting any pending read. */
- X if (scp->sc_syscall == SYS_READ)
- X scp->sc_syscall_action = SIG_RESTART;
- X}
- X
- X#else
- X
- Xstatic void AlarmHandler()
- X{
- X alarmPending = 0;
- X}
- X
- X#endif __hpux
- END_OF_FILE
- if test 1440 -ne `wc -c <'alarm.c'`; then
- echo shar: \"'alarm.c'\" unpacked with wrong size!
- fi
- # end of 'alarm.c'
- fi
- if test -f 'alarm.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'alarm.h'\"
- else
- echo shar: Extracting \"'alarm.h'\" \(450 characters\)
- sed "s/^X//" >'alarm.h' <<'END_OF_FILE'
- X/* alarm.h -- seligman 6/92 */
- X
- X/*
- X-- Routines for using the system interval timer to time beeps. Useful
- X-- for implementing the functions in beep.h on systems that don't provide
- X-- a more straightforward BeepWait() equivalent.
- X--
- X-- These routines use the ALRM signal.
- X*/
- X
- X
- X/*
- X-- Set the alarm for a time specified in ms.
- X*/
- Xvoid AlarmSet(/*int time*/);
- X
- X/*
- X-- Wait for the alarm, or return immediately if the alarm isn't set.
- X*/
- Xvoid AlarmWait();
- END_OF_FILE
- if test 450 -ne `wc -c <'alarm.h'`; then
- echo shar: \"'alarm.h'\" unpacked with wrong size!
- fi
- # end of 'alarm.h'
- fi
- if test -f 'beep.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'beep.h'\"
- else
- echo shar: Extracting \"'beep.h'\" \(1424 characters\)
- sed "s/^X//" >'beep.h' <<'END_OF_FILE'
- X/* beep.h -- seligman 5/92 */
- X
- X/*
- X-- Machine-dependent code for sounding a beep.
- X*/
- X
- X#ifndef _BEEP_H
- X#define _BEEP_H
- X
- X
- X/*
- X-- Called exactly once, before any other function in this interface.
- X-- Returns nonzero on error.
- X*/
- Xint BeepInit();
- X
- X
- X/*
- X-- Sound a beep for a time specified in ms.
- X-- The volume is in the range [0..100], and the pitch is in Hz.
- X--
- X-- May return immediately, after the sounding of the beep is completed,
- X-- or any time in between. May be called while a previous beep is still
- X-- sounding, in which case the previous beep finishes before the new one
- X-- begins. Overall timing will be much better if this routine can return
- X-- during the sounding of the beep, especially if it's a "zero-volume beep",
- X-- meaning it's really just the timed pause of silence between tones.
- X-- ("morse.c" tries to do all its thinking during the pauses between beeps,
- X-- mostly in the longer ones between words.)
- X--
- X-- May use the ALRM signal for timing.
- X--
- X-- Returns nonzero on error.
- X*/
- Xint Beep(/*int time, int volume, int pitch*/);
- X
- X
- X/*
- X-- Wait until any currently sounding beeps have completed.
- X-- Returns nonzero on error.
- X*/
- Xint BeepWait();
- X
- X
- X/*
- X-- Clean up any altered state before exiting or suspending the program.
- X-- Returns nonzero on error.
- X*/
- Xint BeepCleanup();
- X
- X
- X/*
- X-- Restore the world when program is resumed after having been suspended.
- X-- Returns nonzero on error.
- X*/
- Xint BeepResume();
- X
- X
- X#endif _BEEP_H
- END_OF_FILE
- if test 1424 -ne `wc -c <'beep.h'`; then
- echo shar: \"'beep.h'\" unpacked with wrong size!
- fi
- # end of 'beep.h'
- fi
- if test -f 'beepHP.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'beepHP.c'\"
- else
- echo shar: Extracting \"'beepHP.c'\" \(4037 characters\)
- sed "s/^X//" >'beepHP.c' <<'END_OF_FILE'
- X/* beepHP.c -- seligman 5/92 */
- X
- X/*
- X-- Implementation of beep.h for HP9000s700 with audio hardware.
- X--
- X-- If the environment variable SPEAKER begins with "E", the external
- X-- audio connection is used. If it begins with "I", the internal speaker
- X-- is used. Otherwise both are used.
- X--
- X-- Compile with the math library "-lm".
- X*/
- X
- X#include "beep.h"
- X#include "alarm.h"
- X#include <stdlib.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <math.h>
- X#include <fcntl.h>
- X#include <malloc.h>
- X
- X
- Xstatic char *AudioDev;
- X
- Xstatic int DoBeep();
- X
- X
- Xint BeepInit()
- X{
- X char *speaker = getenv("SPEAKER");
- X int fd;
- X
- X AudioDev = speaker && toupper(speaker[0])=='E' ? "/dev/audioEL"
- X : speaker && toupper(speaker[0])=='I' ? "/dev/audioIL"
- X : "/dev/audioBL";
- X
- X /*
- X -- A quick check to ensure that we can open the device.
- X */
- X if ((fd = open(AudioDev, O_WRONLY)) < 0) {
- X perror("?? Error opening audio device");
- X return 1;
- X }
- X close(fd);
- X return 0;
- X}
- X
- X
- X/*
- X-- Optimized for the case where volume & pitch don't change (except possibly
- X-- to zero and back) between successive calls.
- X*/
- Xint Beep(time, volume, pitch)
- X int time, volume, pitch;
- X{
- X int rc;
- X
- X AlarmWait();
- X if (volume != 0 && pitch != 0)
- X if ((rc = DoBeep(time, volume, pitch)) != 0)
- X return rc;
- X AlarmSet(time);
- X return 0;
- X}
- X
- X
- Xint BeepWait()
- X{
- X AlarmWait();
- X return 0;
- X}
- X
- X
- Xint BeepCleanup()
- X{
- X return 0;
- X}
- X
- X
- Xint BeepResume()
- X{
- X return 0;
- X}
- X
- X
- X/*----------------------------------------*/
- X
- X#define SamplingRate 8000 /* audio device samples per second */
- X#define NumRamp (SamplingRate / 200) /* # samples in 5ms ramp up/down */
- X
- Xtypedef short int Sample;
- X#define MaxSample (Sample)0x7FFF
- X
- X
- X/*
- X-- Sound a beep.
- X-- Optimized for the case where volume & pitch don't change between successive
- X-- calls.
- X*/
- Xstatic int DoBeep(time, volume, pitch)
- X int time, volume, pitch;
- X{
- X static int audioDevFD = -1; /* -1 indicates not yet open. */
- X
- X /* Save sample buffer from call to call, and reuse it when possible. */
- X static Sample *buf = NULL;
- X static int bufLen = 0;
- X static int bufVolume = 0;
- X static int bufPitch = 0;
- X
- X Sample rampbuf[NumRamp]; /* Sample buffer for ramp-down. */
- X
- X /* Are volume and pitch same as previous call? */
- X int sameVP = (volume == bufVolume && pitch == bufPitch);
- X
- X int i, j;
- X int numSamples = SamplingRate * time / 1000;
- X
- X /*
- X -- It seems that the first write to the audio device after it's
- X -- been opened must be the longest.
- X */
- X if (numSamples > bufLen) {
- X if (audioDevFD >= 0) close(audioDevFD);
- X audioDevFD = -1;
- X }
- X if (audioDevFD < 0) {
- X if ((audioDevFD = open(AudioDev, O_WRONLY)) < 0) {
- X perror("?? Error opening audio device");
- X return 1;
- X }
- X }
- X
- X /*
- X -- Allocate space for sample buffer. Set "i" to lowest index in
- X -- need of updating.
- X */
- X i = sameVP ? bufLen : 0;
- X if (numSamples > bufLen) {
- X if (sameVP) {
- X buf = realloc(buf, numSamples * sizeof(Sample));
- X } else {
- X if (buf != NULL) free(buf);
- X bufVolume = volume;
- X bufPitch = pitch;
- X buf = malloc(numSamples * sizeof(Sample));
- X }
- X if (buf == NULL) {
- X fprintf(stderr, "?? Buy more memory.\n");
- X return 1;
- X }
- X bufLen = numSamples;
- X }
- X
- X /*
- X -- Update any newly-allocated tail of sample buffer. The ramp-up is
- X -- handled here (since it always occurs at the same place); the ramp-down
- X -- is handled later.
- X */
- X while (i < bufLen) {
- X double rampScale = (i < NumRamp) ? (double) i / NumRamp : 1;
- X double t = (double) i / SamplingRate;
- X buf[i++] =
- X sin(2 * M_PI * pitch * t) * MaxSample * rampScale * volume / 100;
- X }
- X
- X /* Sound the beep, except for the ramp-down. */
- X write(audioDevFD, buf, (numSamples - NumRamp) * sizeof(Sample));
- X
- X /* Ramp-down */
- X for (i = 0, j = numSamples-NumRamp; i < NumRamp; i++, j++)
- X rampbuf[i] = buf[j] * ((double) (NumRamp - i) / NumRamp);
- X write(audioDevFD, rampbuf, sizeof rampbuf);
- X
- X return 0;
- X}
- END_OF_FILE
- if test 4037 -ne `wc -c <'beepHP.c'`; then
- echo shar: \"'beepHP.c'\" unpacked with wrong size!
- fi
- # end of 'beepHP.c'
- fi
- if test -f 'beepSun.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'beepSun.c'\"
- else
- echo shar: Extracting \"'beepSun.c'\" \(4157 characters\)
- sed "s/^X//" >'beepSun.c' <<'END_OF_FILE'
- X/*
- X * If the audio library or audio include files are missing, you need
- X * to get /usr/demo/SOUND off the Sun OS tapes or CD.
- X *
- X * This routine will turn your audio device up to full volume, but
- X * will not attempt to reset the current speaker / jack choice.
- X *
- X * The sun speaker has a residual "click" each time it switches from
- X * silence to tone that I am unable to rid it of.
- X */
- X
- X/* beepSun.c -- seligman 6/92 */
- X
- X/*
- X-- Implementation of beep.h for Sun.
- X-- Rick to Joe to Scott to Joe.
- X*/
- X
- X/* Date: Fri, 2 Aug 91 08:26:08 PDT */
- X/* From: rick@st.unocal.com (Richard Ottolini) */
- X
- X/* Revised: Joe Dellinger */
- X/* Sat Nov 28 02:30:32 HST 1992 */
- X
- X#include "beep.h"
- X#include <sun/audioio.h>
- X#include </usr/demo/SOUND/multimedia/libaudio.h>
- X#include </usr/demo/SOUND/multimedia/ulaw2linear.h>
- X#include <stropts.h>
- X#include <math.h>
- X#include <fcntl.h>
- X
- X
- X#define RATE (8000) /* 8 K samples = 1 second */
- X#define RAMP (RATE * 10 / 1000) /* 10 millisecond ramp */
- X#define MAXTIME (2 * RATE) /* 2 seconds max tone time */
- X
- Xstatic int audio;
- Xstatic audio_info_t audio_stat;
- X
- Xint
- XBeepInit ()
- X{
- X audio = open ("/dev/audio", O_WRONLY);
- X
- X if (audio < 0)
- X /* Uh oh! */
- X return 1;
- X else
- X {
- X /*
- X * Turn the speaker (or headphone, whichever the user has it set to)
- X * up to full volume.
- X */
- X ioctl (audio, AUDIO_GETINFO, &audio_stat);
- X audio_stat.play.gain = AUDIO_MAX_GAIN;
- X ioctl (audio, AUDIO_SETINFO, &audio_stat);
- X
- X return 0;
- X }
- X}
- X
- X
- Xint
- XBeep (time, volume, pitch)
- X int time, volume, pitch;
- X{
- Xstatic unsigned char silence[MAXTIME];
- Xstatic unsigned char soundbuf[MAXTIME - RAMP];
- Xstatic unsigned char ramp_down[RAMP];
- Xstatic int last_pitch = -1, last_n = -1, last_volume = -1;
- Xstatic int first_time = 1;
- X
- Xint i, n, first_len, down_len, cycle;
- Xdouble dt;
- X
- X/*
- X * Initialize the sound of silence
- X */
- X if (first_time == 1)
- X {
- X for (i = 0; i < MAXTIME; i++)
- X silence[i] = (unsigned char) 0;
- X first_time = 0;
- X }
- X
- X
- X/*
- X * Finagle the number of samples
- X */
- X n = (time / 1000.) * RATE; /* Number samples in tone time */
- X n = n < MAXTIME ? n : MAXTIME; /* clip to buffer size */
- X n = n < 2 * RAMP ? 2 * RAMP : n; /* leave room for ramps */
- X
- X/*
- X * Catch stupidity
- X */
- X if (pitch <= 0)
- X volume = 0;
- X
- X
- X if (volume <= 0)
- X {
- X write (audio, silence, n);
- X }
- X else
- X {
- X/*
- X * clip to Nyquist
- X * (Of course this means that if you ask for too high a frequency you
- X * just get silence, since you sample all the zero-crossings of the
- X * sine wave.)
- X */
- X pitch = pitch < RATE / 2 ? pitch : RATE / 2;
- X cycle = ((RATE + 1.e-6) / pitch); /* samples per cycle */
- X
- X if (cycle > MAXTIME / 2)
- X cycle = MAXTIME / 2;
- X
- X /* round down length of (rampup + mesa top) to integral cycle */
- X first_len = ((n - RAMP) / cycle) * cycle;
- X if (first_len < cycle)
- X first_len = cycle;
- X if (first_len > MAXTIME - RAMP)
- X first_len = MAXTIME - RAMP;
- X
- X /* round down length of (rampdown) to integral cycle */
- X down_len = ((RAMP) / cycle) * cycle;
- X if (down_len < cycle)
- X down_len = cycle;
- X if (down_len > RAMP)
- X down_len = RAMP;
- X
- X/*
- X * Can we just reuse what we had before?
- X */
- X if (pitch != last_pitch || n > last_n || volume != last_volume)
- X {
- X last_pitch = pitch;
- X last_n = n;
- X last_volume = volume;
- X
- X dt = 2. * M_PI / cycle; /* sine scale factor */
- X
- X/* Ramp up; begin with silence */
- X
- X for (i = 0; i < RAMP; i++)
- X {
- X soundbuf[i] = audio_l2u (audio_d2l (
- X ((float) i / RAMP) * (volume / 100.) * sin (i * dt)
- X ));
- X }
- X
- X/* Mesa top */
- X for (i = RAMP; i < first_len; i++)
- X {
- X soundbuf[i] = audio_l2u (audio_d2l (
- X 1. * (volume / 100.) * sin (i * dt)
- X ));
- X }
- X
- X/* Ramp down; end with silence */
- X for (i = 0; i < down_len; i++)
- X {
- X ramp_down[i] = audio_l2u (audio_d2l (
- X (1. - (float) (i + 1) / down_len) * (volume / 100.) * sin (i * dt)
- X ));
- X }
- X }
- X
- X write (audio, soundbuf, first_len);
- X write (audio, ramp_down, down_len);
- X }
- X
- X return 0;
- X}
- X
- X
- Xint
- XBeepWait ()
- X{
- X ioctl (audio, AUDIO_DRAIN);
- X return 0;
- X}
- X
- X
- Xint
- XBeepCleanup ()
- X{
- X return 0;
- X}
- X
- X
- Xint
- XBeepResume ()
- X{
- X return 0;
- X}
- END_OF_FILE
- if test 4157 -ne `wc -c <'beepSun.c'`; then
- echo shar: \"'beepSun.c'\" unpacked with wrong size!
- fi
- # end of 'beepSun.c'
- fi
- if test -f 'beepX11.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'beepX11.c'\"
- else
- echo shar: Extracting \"'beepX11.c'\" \(1293 characters\)
- sed "s/^X//" >'beepX11.c' <<'END_OF_FILE'
- X/* beepX11.c -- seligman 5/92 */
- X
- X/*
- X-- Implementation of beep.h for X11.
- X--
- X-- Compile with the library "-lX11".
- X*/
- X
- X#include "beep.h"
- X#include <X11/Xlib.h>
- X
- X
- Xstatic Display *dpy = 0;
- Xstatic XKeyboardControl initialState;
- X
- X#define BellFlags (KBBellPercent | KBBellPitch | KBBellDuration)
- X
- X
- Xint BeepInit()
- X{
- X XKeyboardState state;
- X
- X if (! (dpy = XOpenDisplay(0))) {
- X perror("Couldn't open display");
- X return 1;
- X }
- X
- X /* Save initial state so it can be restored later. */
- X XGetKeyboardControl(dpy, &state);
- X initialState.bell_duration = state.bell_duration;
- X initialState.bell_percent = state.bell_percent;
- X initialState.bell_pitch = state.bell_pitch;
- X
- X return 0;
- X}
- X
- X
- Xint Beep(time, volume, pitch)
- X int time, volume, pitch;
- X{
- X XKeyboardControl values;
- X
- X AlarmWait();
- X
- X if (volume != 0 && pitch != 0) {
- X values.bell_duration = time;
- X values.bell_percent = 100;
- X values.bell_pitch = pitch;
- X
- X XChangeKeyboardControl(dpy, BellFlags, &values);
- X XBell(dpy, volume - 100);
- X XFlush(dpy);
- X }
- X
- X AlarmSet(time);
- X return 0;
- X}
- X
- X
- Xint BeepWait()
- X{
- X AlarmWait();
- X return 0;
- X}
- X
- X
- Xint BeepCleanup()
- X{
- X if (dpy != 0) {
- X XChangeKeyboardControl(dpy, BellFlags, &initialState);
- X XFlush(dpy);
- X }
- X return 0;
- X}
- X
- X
- Xint BeepResume()
- X{
- X return 0;
- X}
- END_OF_FILE
- if test 1293 -ne `wc -c <'beepX11.c'`; then
- echo shar: \"'beepX11.c'\" unpacked with wrong size!
- fi
- # end of 'beepX11.c'
- fi
- if test -f 'morse.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'morse.c'\"
- else
- echo shar: Extracting \"'morse.c'\" \(43613 characters\)
- sed "s/^X//" >'morse.c' <<'END_OF_FILE'
- X/*
- X * A morse code practice utility. (Contains those characters that can appear
- X * on the FCC ham license exam.)
- X *
- X * Running "morse" without arguments or input gives self-doc.
- X *
- X * It doesn't keep PERFECT time, but it seems reasonably close
- X * for reasonable word speeds on my slow SUN IPC!
- X *
- X * Joe Dellinger
- X * Tue Aug 11 14:01:02 HST 1992
- X * University of Hawaii at Manoa
- X *
- X * Revised by Joe:
- X * Thu Nov 26 03:24:19 HST 1992
- X *
- X * Legal stuff:
- X * This code is (ridiculously) heavily modified from morse.c from the Reno UNIX
- X * distribution. I (Joe) also used slightly modified versions of a subroutine
- X * from Richard Ottolini at Unocal for Sun workstation tone generation.
- X * Scott Seligman at Stanford added support for other sorts of devices and
- X * made several other changes. John Shalamskas helped test and made comments.
- X *
- X * I don't think anybody cares if you redistribute this, modify it, etc...
- X * But don't claim you wrote it, try to sell it, or take anyone's name out
- X * of the code! If you modify it, PLEASE INDICATE WHEN, WHERE, AND HOW
- X * YOU MODIFIED IT IN THE COMMENT BELOW. Please.
- X */
- X/*
- X * Joe Dellinger, UH Manoa, inserted this sample modification entry June 1992.
- X */
- X
- X/*
- X * The following stuff is here because this started life as a routine from
- X * the Reno UNIX distribution. (It's also a good boilerplate bit of legalese
- X * to have in there anyway.)
- X */
- X/*
- X * Copyright (c) 1988 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms, with or without
- X * modification, are permitted provided that the following conditions
- X * are met:
- X * 1. Redistributions of source code must retain the above copyright
- X * notice, this list of conditions and the following disclaimer.
- X * 2. Redistributions in binary form must reproduce the above copyright
- X * notice, this list of conditions and the following disclaimer in the
- X * documentation and/or other materials provided with the distribution.
- X * 3. All advertising materials mentioning features or use of this software
- X * must display the following acknowledgement:
- X * This product includes software developed by the University of
- X * California, Berkeley and its contributors.
- X * 4. Neither the name of the University nor the names of its contributors
- X * may be used to endorse or promote products derived from this software
- X * without specific prior written permission.
- X *
- X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- X * SUCH DAMAGE.
- X */
- X
- X#ifndef lint
- Xchar copyright[] =
- X"@(#) Copyright (c) 1988 Regents of the University of California.\n\
- X All rights reserved.\n";
- Xchar copyleftjoe[] =
- X"@(#) Copyright (c) 1992 Joe Dellinger, University of Hawaii at Manoa.\n";
- X#endif /* not lint */
- X
- X/*
- X *============================================================================
- X * Here starts the code!
- X *============================================================================
- X */
- X/*
- X * Useful for seeing what the interleaved reading and writing loops are
- X * really up to.
- X *
- X * #define DEBUG
- X *
- X * If you want to be overwhelmed with information about the probabilities
- X * of each letter being chosen.
- X *
- X * #define DEBUGG
- X */
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <sys/types.h>
- X#include <sys/time.h>
- X#include <ctype.h>
- X#include <signal.h>
- X#include "beep.h"
- X/* Define USG for termio a la System V. */
- X#ifdef __hpux
- X#define USG
- X#endif
- X
- X#define FREQUENCY 800.
- X#define FREQUENCY2 602.
- X#define VOLUME .5
- X#define WORDS_PER_MINUTE 20.
- X#define MAX_BEHINDNESS 0
- X
- Xstatic int whichfrequ = 0;
- Xstatic float frequency1 = FREQUENCY;
- Xstatic float frequency2 = FREQUENCY2;
- Xstatic float frequency;
- Xstatic float volume = VOLUME;
- Xstatic float dot_time;
- Xstatic float dash_time;
- Xstatic float intra_char_time;
- Xstatic float inter_char_time;
- Xstatic float inter_word_time;
- Xstatic float catchup_time;
- Xstatic int showletters = 0;
- Xstatic int showmorse = 0;
- Xstatic int wordsbefore = 0;
- Xstatic int wordsafter = 0;
- Xstatic int fancyending = 1;
- Xstatic int noticebad = 0;
- Xstatic int testing = 0;
- Xstatic int showtesting = 0;
- Xstatic int dynamicspeed = 0;
- Xstatic int charbychar = 0;
- Xstatic int tryagaincount = 1;
- Xstatic float words_per_minute;
- Xstatic float fwords_per_minute;
- Xstatic int randomletters = 0;
- X#define LETMESEE 2
- Xstatic int typeaway = 0;
- X
- Xstatic int totalhitcount = 0;
- Xstatic int totalmisscount = 0;
- Xstatic int helpmeflag = 0;
- X
- X#define MAXWORDLEN 20
- X#define TESTBUFSZ (MAXWORDLEN*10)
- Xstatic int testpointer = -1;
- Xstatic int testlength = 0;
- Xstatic int behindness = 0;
- Xstatic int max_behindness = MAX_BEHINDNESS;
- Xstatic char teststring[TESTBUFSZ];
- Xstatic int yourpointer = -1;
- Xstatic int yourlength = 0;
- Xstatic char yourstring[TESTBUFSZ];
- X
- X/*
- X * How many times can a given character not be asked before
- X * kicking up the probability of asking that one by one randomfactor unit.
- X */
- X#define RIPECOUNT 64
- X
- X#define TWOFIFTYSIX 256
- Xstatic char *(code[TWOFIFTYSIX]);
- Xstatic int errorlog[TWOFIFTYSIX];
- Xstatic int randomfactor[TWOFIFTYSIX];
- Xstatic int randomripe[TWOFIFTYSIX];
- Xextern int testterminal ();
- Xextern int randomletter ();
- X
- X/*
- X * Value of (Wrong - Right), which, if exceeded, will cause the program
- X * to start prompting you. Above MAX_ERROR_THRESHOLD it will never prompt.
- X * Don't let the user bank too much credit for past correct answers;
- X * limit it by min(ERROR_FLOOR, error_threshold).
- X */
- X#define MAX_ERROR_THRESHOLD 1000
- X#define ERROR_FLOOR -3
- Xstatic int error_threshold = MAX_ERROR_THRESHOLD;
- Xstatic int error_floor = ERROR_FLOOR;
- X
- X/*
- X * How many characters behind before it decides you're having
- X * trouble keeping up.
- X */
- X#define BEHIND 1
- X#define WAYBEHIND 3
- X#define TOOFARBEHIND 6
- X/*
- X * If SLOWPOKE or more wpm ticks go by, then it decides you are having lots
- X * of trouble remembering this character, and need to be asked it more
- X * often.
- X */
- X#define SLOWPOKE 10
- X/* You aren't slow -- you left and came back! */
- X#define SLOWPOKEMAX (50 * SLOWPOKE)
- X/*
- X * If FASTPOKE or less wpm ticks go by, then it decides you are good at this
- X * character, and need to be asked it less often.
- X */
- X#define FASTPOKE 4
- X
- X/*
- X * These control how quickly the dynamicspeed option acts when you are
- X * fast or slow. Easier to slow down than speed up!
- X */
- X#define ERRORSLOWER 1.04
- X#define ALOTSLOWER 1.15
- X#define ALITTLESLOWER 1.02
- X#define ALITTLEFASTER 1.02
- X
- X/*
- X * How many inter_char_time's to give you to answer after the end of
- X * a word before considering that you are not keeping up.
- X * Maximum of 2.3, minimum of 0.
- X * The bigger the value, the easier it is to kick in the "automatic
- X * speedup" when using the "-d" option. The maximum means you have (almost)
- X * right up to the beginning of the next word to answer and still have it
- X * count as keeping up.
- X */
- X#define SPORTING_RATIO 1.5
- X
- X/*
- X * The bigger, the more evenly things start out.
- X * (Must be at least 2)
- X */
- X#define RANDOMBASELEVEL 7
- X/*
- X * RANDOMINCWORSE scales how badly you are punished for being wrong
- X * or taking too long. RANDOMINCBETTER scales how you are rewarded for
- X * answering quickly or being right.
- X */
- X#define RANDOMINCWORSE 6
- X#define RANDOMINCBETTER 7
- X#define RANDOMMAX (30 * RANDOMBASELEVEL)
- X/*
- X * The average length of a random word (chosen using exponential distribution).
- X * After implementing this I'm not so sure an exponential distribution
- X * actually models the distribution of real word lengths in English very well.
- X * It's not too bad, though, and the words themselves are all garbage anyway,
- X * so what the heck.
- X */
- X#define RANDWORDLEN 3.5
- X/* Put in a newline instead of a space when past this column */
- X#define RANLINELENGTH 50
- X
- X/* An EOF without the EOF (@) sound */
- X#define SILENTEOF -2
- X/* Toggle tone frequency on control-G within input file */
- X#define FREQU_TOGGLE ((int)'\007')
- X
- X/*
- X * If you want the morse code to come out synchronized with the printing
- X * of dots and dashes with the -m option, then define this. The problem
- X * is that then the morse code then sounds ratty on slower CPU's.
- X * John Shalamskas (KJ9U) suggested turning the precise morse-code printing
- X * synching off because he didn't like the resulting code quality!
- X */
- X#undef FLUSHCODE
- X
- X/*
- X * Choose your favorite random number generator!
- X */
- X#ifndef USERANDOM
- X#ifndef USELRAND
- X#ifndef USERAND
- X#define USERANDOM /* USELRAND or USERAND are the other choices */
- X#endif
- X#endif
- X#endif
- X
- X#ifdef USERANDOM
- X#define RANDOM() random()
- X#define SEEDRANDOM(s) srandom((int)s)
- Xlong random ();
- X#endif
- X#ifdef USELRAND
- X#define RANDOM() lrand48()
- X#define SEEDRANDOM(s) srand48((long)(s))
- Xlong lrand48 ();
- X#endif
- X#ifdef USERAND
- X/*
- X * UGH, are you really sure you want to use this one?
- X * This one really stinks!
- X */
- X#define RANDOM() rand()
- X#define SEEDRANDOM(s) srand((int)(s))
- Xint rand ();
- X#endif
- X
- Xextern die (), cleanup (), suspend ();
- X
- Xmain (argc, argv)
- X int argc;
- X char **argv;
- X{
- Xextern char *optarg;
- Xextern int optind;
- Xint ch;
- Xchar *p;
- Xint ii, jj;
- Xint firsttime, notdoneyet;
- Xint yourchar;
- Xfloat randexp, randnum;
- Xextern time_t time ();
- Xint linepos;
- X
- X if (argc == 1 && isatty (fileno (stdin)))
- X {
- X/*
- X * SELF DOC
- X */
- X printf ("Usage:\n");
- X printf ("morse [options] < text_file\n");
- X printf ("morse [options] words words words\n");
- X printf ("morse [options] -r\n");
- X printf ("morse [options] -i\n");
- X printf ("Options:\n");
- X printf ("-i Play what you type.\n");
- X printf ("-I Like -i but don't turn off keyboard echoing.\n");
- X printf ("-r Generate random text. Starts out slanted towards easy\n");
- X printf (" letters, then slants towards ones you get wrong.\n");
- X printf ("-w words_per_minute (default %g)\n-f frequency_in_hertz (default %g)\n-v volume (zero to one, rather nonlinear, default %g)\n",
- X WORDS_PER_MINUTE, FREQUENCY, VOLUME);
- X printf ("-g alternate_frequency (default %g)\n (toggles via control-G in input FILE at a word break)\n", FREQUENCY2);
- X printf ("-F Farnsworth_character_words_per_minute\n");
- X printf ("-e leave off the EOT sound at the end\n");
- X printf ("-c complain about illegal characters instead of just ignoring them\n");
- X printf ("-b print each word before doing it\n");
- X printf ("-a print each word after doing it\n");
- X printf ("-l print each letter just before doing it\n");
- X printf ("-m print morse dots and dashes as they sound\n");
- X#ifdef FLUSHCODE
- X printf (" (this printing-intensive option slows the wpm down!)\n");
- X#endif
- X printf ("-t Type along with the morse, but don't see what\n");
- X printf (" you're typing (unless you make a mistake).\n");
- X printf (" You are allowed to get ahead as much as you want.\n");
- X printf (" If you get too far behind it will stop and resync with you.\n");
- X printf (" You can force it to resync at the next word end by hitting control-H.\n");
- X printf (" Hit ESC to see how you are doing, control-D to end.\n");
- X printf ("-T Like -t but see your characters (after they are played).\n");
- X printf ("-s Stop after each character and make sure you get it right. (implies -t)\n");
- X printf ("-p NUM (default 0)\n");
- X printf (" Make you get it right NUM times, for penance. (implies -s)\n");
- X printf (" (Yes, NUM = 0 means you can sin all you want.)\n");
- X printf ("-E NUM (default %d)\n", MAX_ERROR_THRESHOLD);
- X printf (" If your count of wrong answers minus right answers for a given character\n");
- X printf (" exceeds this, the program will start prompting you.\n");
- X printf (" If %d or above, it will never prompt. (imples -t)\n", MAX_ERROR_THRESHOLD);
- X printf ("-M NUM (default %d)\n", MAX_BEHINDNESS);
- X printf (" If you get more than this number of characters behind, pause until you\n");
- X printf (" do your next letter. (1 behind is normal, 0 behind means never pause.)\n");
- X printf (" (implies -t)\n");
- X printf ("-d Dynamically speed up or slow down depending on how you are doing.\n");
- X printf (" (if also -s, then -d _only speeds up_!)\n");
- X printf ("\n");
- X printf ("\n");
- X printf ("\n");
- X printf ("For the raw beginner trying to learn morse code I recommend\n");
- X printf ("the following sequence:\n");
- X printf ("\n");
- X printf ("Start learning the alphabet:\n");
- X printf (" morse -r -s -T -d -w 5 -F 15 -p 5 -E -10\n");
- X printf ("Then drill drill drill:\n");
- X printf (" morse -r -s -T -d -w 5 -F 15 -p 5 -E 0\n");
- X printf ("Real-time drill, with hints if you really need it:\n");
- X printf (" morse -r -T -d -w 5 -F 15 -M 2 -E 4\n");
- X printf ("Simulated test:\n");
- X printf (" QSO | morse -e -T -d -w 5 -F 15\n");
- X printf ("and the dreaded random-letter test:\n");
- X printf (" morse -r -T -d -w 5 -F 15\n");
- X printf ("\n");
- X printf ("Written by (mostly) joe@montebello.soest.hawaii.edu\n");
- X exit (0);
- X }
- X
- X for (ii = 0; ii < TWOFIFTYSIX; ii++)
- X code[ii] = NULL;
- X
- X/* Load in the morse code code */
- X code[(int) '0'] = "-----";
- X code[(int) '1'] = ".----";
- X code[(int) '2'] = "..---";
- X code[(int) '3'] = "...--";
- X code[(int) '4'] = "....-";
- X code[(int) '5'] = ".....";
- X code[(int) '6'] = "-....";
- X code[(int) '7'] = "--...";
- X code[(int) '8'] = "---..";
- X code[(int) '9'] = "----.";
- X
- X code[(int) 'a'] = ".-";
- X code[(int) 'b'] = "-...";
- X code[(int) 'c'] = "-.-.";
- X code[(int) 'd'] = "-..";
- X code[(int) 'e'] = ".";
- X code[(int) 'f'] = "..-.";
- X code[(int) 'g'] = "--.";
- X code[(int) 'h'] = "....";
- X code[(int) 'i'] = "..";
- X code[(int) 'j'] = ".---";
- X code[(int) 'k'] = "-.-";
- X code[(int) 'l'] = ".-..";
- X code[(int) 'm'] = "--";
- X code[(int) 'n'] = "-.";
- X code[(int) 'o'] = "---";
- X code[(int) 'p'] = ".--.";
- X code[(int) 'q'] = "--.-";
- X code[(int) 'r'] = ".-.";
- X code[(int) 's'] = "...";
- X code[(int) 't'] = "-";
- X code[(int) 'u'] = "..-";
- X code[(int) 'v'] = "...-";
- X code[(int) 'w'] = ".--";
- X code[(int) 'x'] = "-..-";
- X code[(int) 'y'] = "-.--";
- X code[(int) 'z'] = "--..";
- X
- X /* Punctuation */
- X code[(int) '='] = "-...-";
- X code[(int) '?'] = "..--..";
- X code[(int) '/'] = "-..-.";
- X code[(int) ','] = "--..--";
- X code[(int) '.'] = ".-.-.-";
- X
- X /* Procedural signs */
- X code[(int) '+'] = ".-.-.";
- X code[(int) '@'] = "...-.-";
- X
- X for (ii = 0; ii < TWOFIFTYSIX; ii++)
- X {
- X /* Everything starts equally fresh */
- X randomripe[ii] = 0;
- X /* Start out assuming you know how everything sounds */
- X errorlog[ii] = 0;
- X
- X if (code[ii] == NULL)
- X {
- X /* Ensures these will never be chosen */
- X randomfactor[ii] = 0;
- X }
- X else
- X {
- X /* Start out favoring easy ones */
- X randomfactor[ii] = RANDOMBASELEVEL - strlen (code[ii]);
- X if (randomfactor[ii] < 1)
- X randomfactor[ii] == 1;
- X }
- X }
- X
- X words_per_minute = WORDS_PER_MINUTE;
- X fwords_per_minute = -1.;
- X
- X while ((ch = getopt (argc, argv, "F:w:lbamf:g:v:tTdesp:riIcM:E:")) != EOF)
- X switch ((char) ch)
- X {
- X case 'i':
- X typeaway = 1;
- X break;
- X case 'I':
- X typeaway = LETMESEE;
- X break;
- X case 'r':
- X randomletters = 1;
- X break;
- X case 'c':
- X noticebad = 1;
- X break;
- X case 'e':
- X fancyending = 0;
- X break;
- X case 'T':
- X testing = 1;
- X showtesting = 1;
- X break;
- X case 't':
- X testing = 1;
- X break;
- X case 's':
- X charbychar = 1;
- X testing = 1;
- X break;
- X case 'p':
- X charbychar = 1;
- X testing = 1;
- X sscanf (optarg, "%d", &tryagaincount);
- X break;
- X case 'M':
- X testing = 1;
- X sscanf (optarg, "%d", &max_behindness);
- X if (max_behindness < 1)
- X max_behindness = 0;
- X break;
- X case 'E':
- X testing = 1;
- X sscanf (optarg, "%d", &error_threshold);
- X if (error_threshold < error_floor)
- X error_floor = error_threshold;
- X break;
- X case 'd':
- X dynamicspeed = 1;
- X break;
- X case 'w':
- X sscanf (optarg, "%f", &words_per_minute);
- X break;
- X case 'F':
- X sscanf (optarg, "%f", &fwords_per_minute);
- X break;
- X case 'l':
- X showletters = 1;
- X break;
- X case 'b':
- X wordsbefore = 1;
- X break;
- X case 'a':
- X wordsafter = 1;
- X break;
- X case 'm':
- X showmorse = 1;
- X break;
- X case 'f':
- X sscanf (optarg, "%f", &frequency1);
- X break;
- X case 'g':
- X sscanf (optarg, "%f", &frequency2);
- X break;
- X case 'v':
- X sscanf (optarg, "%f", &volume);
- X if (volume < 0.)
- X volume = 0.;
- X if (volume > 1.)
- X volume = 1.;
- X break;
- X default:
- X fprintf (stderr, "Type \"morse\" without arguments to get self-doc!\n");
- X exit (1);
- X break;
- X }
- X argc -= optind;
- X argv += optind;
- X
- X if (fwords_per_minute <= 0.)
- X fwords_per_minute = words_per_minute;
- X new_words_per_minute ();
- X
- X frequency = frequency1;
- X
- X if (BeepInit () != 0)
- X {
- X fprintf (stderr, "Can't access speaker.\n");
- X exit (1);
- X }
- X
- X signal (SIGINT, die);
- X signal (SIGTERM, die);
- X signal (SIGQUIT, die);
- X signal (SIGTSTP, suspend);
- X
- X if (testing || typeaway)
- X {
- X openterminal ();
- X }
- X
- X/*
- X * Do .25 seconds of silence initially to give the workstation time to
- X * get settled after the stress of starting this program and opening
- X * up everything.
- X */
- X tone (frequency, .25, 0.);
- X toneflush ();
- X
- X if (typeaway)
- X {
- X testing = 0;
- X showtesting = 0;
- X charbychar = 0;
- X wordsbefore = 0;
- X wordsafter = 0;
- X randomletters = 0;
- X
- X notdoneyet = 1;
- X
- X while (notdoneyet)
- X {
- X pollyou ();
- X
- X for (jj = 0; jj < yourlength; jj++)
- X {
- X yourchar = yourstring[(yourpointer - yourlength + 1 + jj + TESTBUFSZ) % TESTBUFSZ];
- X
- X /* Control-D: finished */
- X if (yourchar == (int) '\004')
- X {
- X toneflush ();
- X notdoneyet = 0;
- X break;
- X }
- X
- X if (isspace (yourchar))
- X {
- X if (showletters)
- X {
- X toneflush ();
- X printf ("%c", yourchar);
- X fflush (stdout);
- X }
- X
- X tone (frequency, inter_word_time, 0.);
- X
- X continue;
- X }
- X
- X morse (yourchar);
- X }
- X yourlength -= jj;
- X }
- X }
- X else if (randomletters)
- X {
- X SEEDRANDOM (time (NULL));
- X randexp = 1. / (1. - 1. / (float) (RANDWORDLEN));
- X linepos = 0;
- X while (1)
- X {
- X dowords (randomletter ());
- X linepos++;
- X
- X /* Knock a few bits off the top so we're sure it won't overflow */
- X /* Shift a few bits because the lower bits stink */
- X /* Add in the time so it doesn't repeat from run to run */
- X randnum = (float) (
- X ((RANDOM () >> 9) + (long) (time (NULL)) >> 4)
- X & 0x00FFFFFF);
- X randnum = randnum - randexp * (int) (randnum / randexp);
- X if (randnum >= 1.)
- X if (linepos >= RANLINELENGTH)
- X {
- X dowords ((int) '\n');
- X linepos = 0;
- X }
- X else
- X {
- X dowords ((int) ' ');
- X linepos++;
- X }
- X }
- X }
- X else
- X {
- X if (*argv)
- X {
- X firsttime = 1;
- X
- X do
- X {
- X if (!firsttime)
- X {
- X dowords ((int) ' ');
- X }
- X else
- X firsttime = 0;
- X
- X for (p = *argv; *p; ++p)
- X dowords ((int) *p);
- X } while (*++argv);
- X }
- X else
- X {
- X while ((ch = getchar ()) != EOF)
- X dowords (ch);
- X }
- X }
- X
- X if (fancyending)
- X dowords (EOF);
- X else
- X dowords (SILENTEOF);
- X
- X fflush (stdout);
- X
- X if (testing)
- X {
- X /*
- X * WE'RE completely done, and YOU aren't! Force catch up. (Note if
- X * charbychar = YES we won't get here, since we're always caught up
- X * after each character as it comes out.)
- X */
- X while (testlength > 0)
- X {
- X tone (frequency, catchup_time, 0.);
- X toneflush ();
- X testterminal ();
- X }
- X }
- X
- X /* Just to be sure! */
- X toneflush ();
- X
- X if (showmorse || wordsbefore || wordsafter || showletters || showtesting)
- X printf ("\n");
- X fflush (stdout);
- X
- X if (testing)
- X report ();
- X
- X/* If you make any mistakes exit with a return code! */
- X cleanup ();
- X return (totalmisscount > 0);
- X}
- X
- Xnew_words_per_minute ()
- X{
- Xfloat wtick, ftick, tick;
- X
- X tick = 60. / (words_per_minute * 50);
- X
- X /*
- X * In the limit as wpm goes past fwpm, Farnsworth becomes kosher PARIS
- X */
- X if (fwords_per_minute <= words_per_minute)
- X ftick = 60. / (words_per_minute * 50);
- X else
- X ftick = 60. / (fwords_per_minute * 50);
- X
- X wtick = (50. * tick - 31. * ftick) / 19.;
- X
- X /*
- X * This time is used when the computer is waiting on you to hit a key; it
- X * is useful to scale the granularity with the real overrall words per
- X * minute. This also serves as a measuring rod to see if you are
- X * responding "fast enough". If you are too slow, then obviously you are
- X * having trouble with that character, and should be given it more OFTEN.
- X * Heh heh heh...
- X */
- X catchup_time = tick;
- X
- X /*
- X * Things between characters and words go at the "remainder" speed,
- X * whatever space you need to make the sped-up Farnsworth characters come
- X * out with the correct overall words per minute.
- X */
- X inter_char_time = wtick * 3.;
- X inter_word_time = wtick * 7.;
- X
- X /* Things within the character go at the Farnsworth speed */
- X intra_char_time = ftick;
- X dot_time = ftick;
- X dash_time = ftick * 3.;
- X}
- X
- Xstatic int tryingagain = 0, slowpoke = 0;
- X
- Xdowords (c)
- X int c;
- X{
- Xstatic int wordc = 0;
- Xstatic char word[MAXWORDLEN];
- Xchar *wordp;
- Xint ii;
- Xint againcount;
- Xint are_we_repeating;
- X
- X/*
- X * If a word gets too long, just cut it off by inserting a space.
- X * Just call ourselves with the character we wish we'd gotten...
- X */
- X if (wordc == MAXWORDLEN - 1 && !(isspace (c) || c == EOF || c == SILENTEOF || c == FREQU_TOGGLE))
- X dowords ((int) ' ');
- X
- X if (isspace (c) || c == EOF || c == SILENTEOF || c == FREQU_TOGGLE)
- X {
- X if (wordc > 0)
- X {
- X word[wordc] = '\0';
- X
- X/*
- X * We have just read in a new complete word from the input, (hopefully)
- X * during the time of an inter-word space minus an inter-char space.
- X * Now let's go back and see what happened with the PREVIOUS word,
- X * the one that we had just finished playing. Did the user keep
- X * up with us?
- X */
- X#ifdef DEBUG
- X fprintf (stderr, " [%d] ", behindness);
- X#endif
- X if (testing && dynamicspeed && !charbychar)
- X {
- X /*
- X * (If charbychar then behindness is ALWAYS 0 at this
- X * point...)
- X */
- X if (behindness == 0)
- X {
- X /* You're a speed demon! Speed up a bit, then! */
- X words_per_minute *= ALITTLEFASTER;
- X new_words_per_minute ();
- X }
- X else if (behindness > WAYBEHIND)
- X {
- X /* You're way behind! Slow way down. */
- X words_per_minute /= ALOTSLOWER;
- X new_words_per_minute ();
- X }
- X else if (behindness > BEHIND)
- X {
- X /* You're behind! Slow down a bit. */
- X words_per_minute /= ALITTLESLOWER;
- X new_words_per_minute ();
- X }
- X }
- X
- X
- X/*
- X * If the user was WAY too far behind stop and catch up with
- X * the "new" word as the first one.
- X */
- X if (testing && (behindness > TOOFARBEHIND || helpmeflag))
- X {
- X if (helpmeflag)
- X printf ("\nOK, let's restart.\n");
- X else
- X printf ("\nYou are too far behind! Let's restart.\n");
- X fflush (stdout);
- X
- X toneflush ();
- X
- X /* Flush the keyboard buffer */
- X pollyou ();
- X
- X /* Forget the past */
- X helpmeflag = 0;
- X behindness = 0;
- X testlength = 0;
- X yourlength = 0;
- X
- X /* Give the user a little rest. */
- X sleep (2);
- X printf ("\nWPM now %d\n", (int) (words_per_minute + .5));
- X fflush (stdout);
- X sleep (2);
- X printf ("\nREADY?\n");
- X fflush (stdout);
- X sleep (1);
- X printf ("\nSET\n");
- X fflush (stdout);
- X sleep (1);
- X printf ("\nGO!\n");
- X fflush (stdout);
- X }
- X
- X/*
- X * Start treating the new word.
- X */
- X if (wordsbefore)
- X {
- X /* Try to keep your out-of-sync text from getting swirled in */
- X if (showtesting)
- X printf ("\n");
- X
- X printf ("%s", word);
- X
- X if (showmorse || showletters || wordsafter || showtesting)
- X {
- X printf (" ");
- X for (ii = 0; ii < 16 - (wordc + 2); ii++)
- X {
- X printf (" ");
- X }
- X }
- X
- X fflush (stdout);
- X }
- X
- X if (testing && charbychar)
- X {
- X againcount = 0;
- X }
- X
- X for (wordp = word; *wordp != '\0'; wordp++)
- X {
- X tryingagain = 0;
- X
- X tryagain:
- X if (testing && !tryingagain && !showletters &&
- X error_threshold < MAX_ERROR_THRESHOLD &&
- X errorlog[(int) *wordp] > error_threshold)
- X {
- X toneflush ();
- X /* Give them a quick hint */
- X printf ("[%c]", *wordp);
- X fflush (stdout);
- X
- X morse (*wordp);
- X
- X toneflush ();
- X if (!showmorse)
- X {
- X /* Erase the hint */
- X printf ("\b\b\b \b\b\b", *wordp);
- X fflush (stdout);
- X }
- X }
- X else
- X {
- X morse (*wordp);
- X }
- X
- X if (testing)
- X {
- X if (charbychar)
- X {
- X toneflush ();
- X /* Force catchup */
- X slowpoke = 0;
- X while (behindness > 0)
- X {
- X if (testterminal () && tryagaincount > 0)
- X {
- X /*
- X * OOPS! They got it WRONG! MAKE THEM TRY
- X * AGAIN!
- X */
- X printf ("Try again.\n");
- X /*
- X * Yeah I know gotos are inelegant but I
- X * don't feel like figuring out the "elegant"
- X * way to do this right now.
- X */
- X againcount = tryagaincount - 1;
- X tryingagain = 1;
- X goto tryagain;
- X }
- X else
- X {
- X /*
- X * They got it right, or they didn't answer
- X * yet.
- X */
- X if (behindness > 0)
- X {
- X /*
- X * They are STILL thinking, the
- X * slowpokes. Wait a bit before trying
- X * again.
- X */
- X tone (frequency, catchup_time, 0.);
- X /*
- X * Keep track of how long they're taking
- X * to answer!
- X */
- X if (slowpoke < SLOWPOKEMAX)
- X slowpoke++;
- X toneflush ();
- X }
- X else if (dynamicspeed && !slowpoke && !tryingagain)
- X {
- X /*
- X * They got it right without errors the
- X * first time and we didn't have to wait
- X * for them! A speed demon! Speed up a
- X * bit, then!
- X */
- X words_per_minute *= ALITTLEFASTER;
- X new_words_per_minute ();
- X }
- X }
- X }
- X
- X /* Insufficient penance? */
- X if (againcount > 0)
- X {
- X againcount--;
- X goto tryagain;
- X }
- X }
- X else
- X {
- X testterminal ();
- X /*
- X * Stop if we get more than max_behindness ahead.
- X * max_behindness == 0 means don't worry about them,
- X * they can be as far behind as they want and we
- X * won't stop!
- X */
- X if (max_behindness > 0)
- X {
- X are_we_repeating = 0;
- X while (behindness >= max_behindness)
- X {
- X#ifdef DEBUG
- X fprintf (stderr, " (%d) ", behindness);
- X#endif
- X if (are_we_repeating)
- X {
- X /*
- X * Pause for a bit so we don't loop too
- X * fast
- X */
- X tone (frequency, catchup_time, 0.);
- X }
- X else
- X {
- X are_we_repeating = 1;
- X }
- X /* Finish playing whatever we're playing */
- X toneflush ();
- X /* And give them another chance */
- X testterminal ();
- X }
- X }
- X }
- X }
- X }
- X
- X toneflush ();
- X if (testing)
- X testterminal ();
- X
- X if (wordsafter)
- X {
- X printf (" (%s)", word);
- X }
- X
- X if (wordsbefore || wordsafter || showmorse)
- X printf ("\n");
- X else if (showletters || showtesting)
- X {
- X if (c != EOF && c != SILENTEOF && c != FREQU_TOGGLE)
- X {
- X if (showletters)
- X printf ("%c", c);
- X
- X if (showtesting)
- X testaddchar (c);
- X }
- X }
- X
- X/*
- X * WHEW! FINISHED QUEUEING THE WORD FOR PLAYING!
- X * Now finish up all the other sundry details...
- X */
- X
- X /* Flush the output printing queue... */
- X fflush (stdout);
- X /*
- X * Pause for a bit; this gives the user a sporting chance at
- X * catching up with us.
- X */
- X tone (frequency, SPORTING_RATIO * inter_char_time, 0.);
- X toneflush ();
- X /* Start sounding an inter-word space */
- X tone (frequency, inter_word_time - SPORTING_RATIO * inter_char_time, 0.);
- X
- X /* While that silence is playing check if the user has caught up. */
- X if (testing)
- X testterminal ();
- X
- X /* We finished this word; reset the word character count */
- X wordc = 0;
- X }
- X else if (!(wordsbefore || wordsafter || showmorse)
- X &&
- X (showletters || showtesting))
- X {
- X if (c != EOF && c != SILENTEOF && c != FREQU_TOGGLE)
- X {
- X if (showletters)
- X printf ("%c", c);
- X
- X if (showtesting)
- X testaddchar (c);
- X }
- X }
- X
- X if (c == EOF)
- X {
- X morse (EOF);
- X toneflush ();
- X }
- X else if (c == SILENTEOF)
- X {
- X toneflush ();
- X }
- X else if (c == FREQU_TOGGLE)
- X {
- X /* Switch to the other frequency */
- X /* (Won't work from keyboard, only from a file.) */
- X whichfrequ = 1 - whichfrequ;
- X switch (whichfrequ)
- X {
- X case 1:
- X frequency = frequency2;
- X break;
- X case 0:
- X default:
- X frequency = frequency1;
- X break;
- X }
- X }
- X }
- X else
- X {
- X word[wordc++] = c;
- X }
- X}
- X
- X/*
- X * Don't try to test the person DURING the call into morse!
- X */
- Xmorse (c)
- X int c;
- X{
- X if (showletters)
- X {
- X if (c == EOF)
- X printf ("EOT");
- X else if (c == '.' && showmorse)
- X printf ("PERIOD");
- X else if (c == '=' && showmorse)
- X printf ("BREAK");
- X else
- X printf ("%c", c);
- X
- X fflush (stdout);
- X }
- X
- X if (isalpha (c))
- X {
- X if (testing)
- X testaddchar (c - (isupper (c) ? 'A' : 'a') + 'a');
- X show (code[c - (isupper (c) ? 'A' : 'a') + 'a']);
- X }
- X else if (c == EOF)
- X {
- X show (code[(int) '@']);
- X }
- X else if (code[c] != NULL)
- X {
- X if (testing)
- X testaddchar (c);
- X show (code[c]);
- X }
- X else
- X {
- X /* Oops! This letter is junk! */
- X
- X if (noticebad)
- X {
- X if (showletters)
- X {
- X fflush (stdout);
- X }
- X
- X /* Simulate a stumble */
- X tone (frequency, 2. * inter_word_time, 0.);
- X toneflush ();
- X }
- X
- X if (showletters)
- X {
- X /* Wipe out what we just printed */
- X fflush (stdout);
- X printf ("\b");
- X printf (" ");
- X printf ("\b");
- X fflush (stdout);
- X }
- X
- X if (noticebad)
- X {
- X if (showletters)
- X {
- X /* And replace it with an error message */
- X printf ("*UNKNOWN_CHARACTER*");
- X fflush (stdout);
- X }
- X
- X /* Give the error call */
- X show ("........");
- X
- X /* Regroup */
- X tone (frequency, inter_word_time, 0.);
- X }
- X }
- X
- X if (showmorse)
- X printf (" ");
- X fflush (stdout);
- X toneflush ();
- X tone (frequency, inter_char_time - intra_char_time, 0.);
- X}
- X
- X
- X/*
- X * Don't try to test the person WHILE doing dots and dashes!
- X */
- Xshow (s)
- X char *s;
- X{
- Xchar c;
- X
- X while ((c = *s++) != '\0')
- X {
- X tone (frequency, intra_char_time, 0.);
- X
- X#ifdef FLUSHCODE
- X if (showmorse)
- X toneflush ();
- X#endif
- X
- X switch (c)
- X {
- X case '.':
- X tone (frequency, dot_time, volume);
- X break;
- X case '-':
- X tone (frequency, dash_time, volume);
- X break;
- X }
- X
- X if (showmorse)
- X {
- X printf ("%c", c);
- X fflush (stdout);
- X#ifdef FLUSHCODE
- X toneflush ();
- X#endif
- X }
- X }
- X}
- X
- X/*
- X * This only gets passed valid characters: ones
- X * that have a morse code associated with them
- X * or ones for which isspace(c) is true.
- X */
- Xtestaddchar (c)
- X char c;
- X{
- X testpointer = (testpointer + 1) % TESTBUFSZ;
- X teststring[testpointer] = c;
- X#ifdef DEBUG
- X fprintf (stderr, " (%c,%d,%d) ", c, testlength, behindness);
- X#endif
- X testlength++;
- X if (testlength > TESTBUFSZ)
- X {
- X fprintf (stderr, "\n\nInput buffer queue overflow! Make TESTBUFSZ bigger!\n");
- X fprintf (stderr, "(Or don't fall so far behind)\n");
- X
- X die ();
- X }
- X
- X/*
- X * Since you are never asked to type spaces (you can type them if
- X * you want, but they are ignored) spaces in the input file don't
- X * count against your "behindness".
- X */
- X if (!isspace (c))
- X behindness++;
- X}
- X
- Xyouraddchar (c)
- X char c;
- X{
- X yourpointer = (yourpointer + 1) % TESTBUFSZ;
- X yourstring[yourpointer] = c;
- X#ifdef DEBUG
- X fprintf (stderr, " <%c,%d> ", c, yourlength);
- X#endif
- X yourlength++;
- X if (yourlength > TESTBUFSZ)
- X {
- X fprintf (stderr, "\n\nKeyboard typeahead buffer queue overflow! Make TESTBUFSZ bigger!\n");
- X fprintf (stderr, "(Or don't type so far ahead... how did you expect to get them right anyway?)\n");
- X
- X die ();
- X }
- X}
- X
- Xpollyou ()
- X{
- Xint ii, num;
- Xchar *string;
- X
- X num = readterminal (&string);
- X
- X for (ii = 0; ii < num; ii++)
- X youraddchar (string[ii]);
- X}
- X
- Xint
- Xtestterminal ()
- X{
- Xint testinc, yourinc;
- Xint correctchar, yourchar, yourcharnocase;
- Xint errorcount;
- X
- X errorcount = 0;
- X
- X/*
- X * There is nothing in the input file queue right now,
- X * so we can't process any of your keystrokes.
- X * Defer processing until we can catch up with YOU!
- X */
- X if (testlength == 0)
- X return errorcount;
- X
- X /* We're ready for you; but are you ready for us? */
- X pollyou ();
- X
- X/*
- X * Process your entries and the input queue entries in parallel
- X */
- X if (yourlength > 0 && testlength > 0)
- X {
- X for (testinc = 0, yourinc = 0;
- X testinc < testlength && yourinc < yourlength;
- X testinc++, yourinc++)
- X {
- X correctchar = teststring[(testpointer - testlength + 1 + testinc + TESTBUFSZ) % TESTBUFSZ];
- X
- X /*
- X * The latter half of this if shouldn't be necessary, but just in
- X * case...
- X */
- X if (isspace (correctchar) || code[correctchar] == NULL)
- X {
- X if (showtesting)
- X {
- X printf ("%c", correctchar);
- X fflush (stdout);
- X }
- X
- X /* White space doesn't count for "behindness" */
- X behindness++;
- X /* The _other_ pointer wasn't used; don't increment it. */
- X yourinc--;
- X
- X /* Short circuit the loop */
- X continue;
- X }
- X
- X
- X yourchar = yourstring[(yourpointer - yourlength + 1 + yourinc + TESTBUFSZ) % TESTBUFSZ];
- X if (isalpha (yourchar))
- X yourcharnocase = yourchar - (isupper (yourchar) ? 'A' : 'a') + 'a';
- X else
- X yourcharnocase = yourchar;
- X
- X /* Did you type something rude? If so, just ignore it. */
- X if (isspace (yourchar) || code[yourcharnocase] == NULL)
- X {
- X /* ESCAPE: dump status info */
- X /* Control-D: dump status info and then bye bye */
- X /* Control-H: force restart */
- X if (yourchar == '\033' || yourchar == (int) '\004')
- X {
- X report ();
- X
- X if (yourchar == (int) '\004')
- X die ();
- X }
- X else if (yourchar == '\b')
- X {
- X helpmeflag = 1;
- X }
- X
- X /* The _other_ pointer wasn't used; don't increment it. */
- X testinc--;
- X /* Short circuit the loop */
- X continue;
- X }
- X
- X if (yourcharnocase != correctchar)
- X {
- X errorcount++;
- X totalmisscount++;
- X
- X /*
- X * Record that you are having trouble with these.
- X */
- X errorlog[correctchar]++;
- X if (code[yourcharnocase] != NULL &&
- X errorlog[yourcharnocase] < MAX_ERROR_THRESHOLD)
- X errorlog[yourcharnocase]++;
- X
- X printf ("\n\007%c (%s) for %c (%s)\n",
- X yourchar, code[yourcharnocase],
- X correctchar, code[correctchar]);
- X fflush (stdout);
- X
- X if (charbychar)
- X {
- X /* Give them a bit of time to think about their error */
- X tone (frequency, inter_word_time, 0.);
- X toneflush ();
- X }
- X if (dynamicspeed && !charbychar)
- X {
- X /*
- X * Slow down. Doesn't make sense to slow down for errors,
- X * though, if you've got all the time you want to think
- X * about each one.
- X */
- X words_per_minute /= ERRORSLOWER;
- X new_words_per_minute ();
- X }
- X if (randomletters && !tryingagain)
- X {
- X /*
- X * Ask ones that confused you more often!
- X */
- X if (code[yourcharnocase] != NULL)
- X {
- X randomfactor[yourcharnocase] += (3 * RANDOMINCWORSE / 2);
- X if (randomfactor[yourcharnocase] > RANDOMMAX)
- X randomfactor[yourcharnocase] = RANDOMMAX;
- X }
- X
- X randomfactor[correctchar] += RANDOMINCWORSE * 2;
- X if (randomfactor[correctchar] > RANDOMMAX)
- X randomfactor[correctchar] = RANDOMMAX;
- X }
- X }
- X else
- X {
- X /*
- X * Record that you got this right.
- X */
- X if (!tryingagain)
- X {
- X totalhitcount++;
- X if (errorlog[correctchar] > error_floor)
- X errorlog[correctchar]--;
- X }
- X
- X if (showtesting)
- X {
- X printf ("%c", yourchar);
- X fflush (stdout);
- X }
- X
- X if (randomletters && !tryingagain)
- X {
- X if (slowpoke == SLOWPOKEMAX)
- X {
- X printf ("\nNice to have you back again, I was getting bored!\n");
- X }
- X else if (slowpoke >= SLOWPOKE * 3)
- X {
- X /*
- X * Did you take too long thinking about it? If so,
- X * you probably need to be asked this one more
- X * often...
- X */
- X randomfactor[correctchar] += (3 * RANDOMINCWORSE / 2);
- X if (randomfactor[correctchar] > RANDOMMAX)
- X randomfactor[correctchar] = RANDOMMAX;
- X
- X /*
- X * Hits this slow shouldn't count! You were obviously
- X * just guessing! (But it doesn't count as an error
- X * either.)
- X */
- X totalhitcount--;
- X }
- X else if (slowpoke > FASTPOKE)
- X {
- X randomfactor[correctchar] +=
- X (slowpoke * RANDOMINCWORSE) / (2 * SLOWPOKE);
- X if (randomfactor[correctchar] > RANDOMMAX)
- X randomfactor[correctchar] = RANDOMMAX;
- X }
- X else if (slowpoke <= (FASTPOKE / 2))
- X {
- X /*
- X * Ask ones that you quickly answer correctly less
- X * often!
- X */
- X randomfactor[correctchar] -= (3 * RANDOMINCBETTER / 2);
- X /*
- X * Don't let randomfactor hit 0, or you'll NEVER be
- X * asked this one AGAIN!
- X */
- X if (randomfactor[correctchar] < 1)
- X randomfactor[correctchar] = 1;
- X }
- X else if (slowpoke <= FASTPOKE)
- X {
- X randomfactor[correctchar] -= (RANDOMINCBETTER / 2);
- X if (randomfactor[correctchar] < 1)
- X randomfactor[correctchar] = 1;
- X }
- X }
- X }
- X
- X }
- X testlength -= testinc;
- X behindness -= testinc;
- X yourlength -= yourinc;
- X }
- X
- X/*
- X * If there are some extra white space characters in the input queue
- X * it's OK, we'll get to them next time or we'll clean them out at the
- X * end.
- X */
- X return errorcount;
- X}
- X
- X
- X/*----------------------------------------*/
- X
- Xtone (hertz, duration, amplitude)
- X float hertz, duration, amplitude;
- X{
- X Beep ((int) (duration * 1000), (int) (amplitude * 100), (int) hertz);
- X}
- X
- X
- Xtoneflush ()
- X{
- X BeepWait ();
- X}
- X
- X
- X/*----------------------------------------*/
- X
- X#include <sys/ioctl.h>
- X#include <fcntl.h>
- X#ifdef USG
- X#include <sys/termio.h>
- Xstruct termio oldtermgtty;
- Xstruct termio termgtty;
- X#else
- X#include <sys/file.h>
- Xstruct sgttyb oldtermgtty;
- Xstruct sgttyb termgtty;
- X#endif
- Xstatic char *terminal = "/dev/tty";
- Xstatic int termfd;
- Xstatic int oldflgs, newflgs;
- Xstatic int termopen = 0;
- X
- Xopenterminal ()
- X{
- X /* get parameters and open terminal */
- X
- X#ifdef USG
- X termfd = open (terminal, O_RDWR | O_NDELAY, 0);
- X ioctl (termfd, TCGETA, &termgtty);
- X oldtermgtty = termgtty;
- X if (typeaway != LETMESEE)
- X termgtty.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
- X termgtty.c_lflag &= ~ICANON;
- X termgtty.c_cc[VMIN] = 1;
- X termgtty.c_cc[VTIME] = 0;
- X ioctl (0, TCSETAW, &termgtty);
- X#else
- X termfd = open (terminal, O_RDWR, 0);
- X ioctl (termfd, TIOCGETP, &termgtty);
- X oldtermgtty = termgtty;
- X if (typeaway != LETMESEE)
- X termgtty.sg_flags &= ~ECHO;
- X termgtty.sg_flags |= CBREAK;
- X ioctl (termfd, TIOCSETP, &termgtty);
- X oldflgs = fcntl (termfd, F_GETFL);
- X newflgs = oldflgs | FNDELAY;
- X#endif
- X
- X termopen = 1;
- X}
- X
- Xint
- Xreadterminal (string)
- X char **string;
- X{
- X/* This must be declared static! */
- Xstatic char line[TESTBUFSZ];
- Xint n;
- X
- X#ifndef USG
- X fcntl (termfd, F_SETFL, newflgs);
- X#endif
- X n = read (termfd, line, sizeof (line) - 1);
- X#ifndef USG
- X fcntl (termfd, F_SETFL, oldflgs);
- X#endif
- X
- X if (n > 0)
- X {
- X line[n] = '\0';
- X *string = line;
- X }
- X else
- X *string = NULL;
- X
- X return n;
- X}
- X
- Xcloseterminal ()
- X{
- X#ifdef USG
- X ioctl (termfd, TCSETAW, &oldtermgtty);
- X#else
- X ioctl (termfd, TIOCSETP, &oldtermgtty);
- X#endif
- X close (termfd);
- X}
- X
- Xdie ()
- X{
- X cleanup ();
- X exit (1);
- X}
- X
- Xcleanup ()
- X{
- X if (termopen)
- X closeterminal ();
- X BeepCleanup ();
- X}
- X
- Xsuspend ()
- X{
- X signal (SIGTSTP, suspend);
- X cleanup ();
- X kill (getpid (), SIGSTOP);
- X if (termopen)
- X openterminal ();
- X BeepResume ();
- X}
- X
- X
- X/*----------------------------------------*/
- X
- Xint
- Xrandomletter ()
- X{
- Xint ii;
- Xint sum, sum2;
- Xlong ranspot;
- Xextern time_t time ();
- Xstatic int lasttime = -1;
- Xstatic long norepeat;
- X
- X/*
- X * This keeps the not-so-random random number generator from ignoring
- X * certain characters forever!
- X */
- X norepeat = ((long) time (NULL) / 31) % 17291;
- X
- X/*
- X * All the usable letters get one unit riper.
- X */
- X for (ii = 0; ii < TWOFIFTYSIX; ii++)
- X {
- X if (randomfactor[ii] > 0)
- X {
- X#ifdef DEBUGG
- X fprintf (stderr, "%c: %d %d\n",
- X (char) ii, randomfactor[ii], randomripe[ii]);
- X#endif
- X randomripe[ii]++;
- X }
- X }
- X
- X sum = 0;
- X for (ii = 0; ii < TWOFIFTYSIX; ii++)
- X sum += (randomfactor[ii] + (int) (randomripe[ii] / RIPECOUNT));
- X
- X/*
- X * The low bits of random aren't very random, I don't care WHAT
- X * the manual claims.
- X */
- X do
- X {
- X ranspot = ((RANDOM () >> 4) % sum + norepeat) % sum;
- X
- X sum2 = 0;
- X for (ii = 0; ii < TWOFIFTYSIX - 1; ii++)
- X {
- X sum2 += (randomfactor[ii] + (int) (randomripe[ii] / RIPECOUNT));
- X
- X if (sum2 > ranspot)
- X break;
- X }
- X /* Do it again if you got the same as last time! */
- X } while (ii == lasttime);
- X
- X /* This one is FRESH again. */
- X randomripe[ii] = 0;
- X /* Remember for next time. */
- X lasttime = ii;
- X
- X return ii;
- X}
- X
- Xreport ()
- X{
- Xint ii, jj, count;
- Xfloat sum;
- Xint randomstr[TWOFIFTYSIX];
- Xextern int rancomp ();
- X
- X printf ("\nCurrent words per minute: %.1f\n", words_per_minute);
- X
- X printf ("Total hits %d, misses %d", totalhitcount, totalmisscount);
- X if (totalmisscount > 0)
- X printf (", hit per miss ratio %.1f\n", (float) totalhitcount / (float) totalmisscount);
- X else
- X printf ("\n");
- X
- X if (randomletters)
- X {
- X printf ("Most to least frequent choices:\n");
- X count = 0;
- X sum = 0.;
- X for (ii = 0; ii < TWOFIFTYSIX; ii++)
- X {
- X if (randomfactor[ii] > 0)
- X {
- X sum += (randomfactor[ii] + (randomripe[ii] / (float) RIPECOUNT));
- X randomstr[count] = ii;
- X count++;
- X }
- X }
- X
- X qsort ((char *) randomstr, count, sizeof (randomstr[0]), rancomp);
- X
- X for (ii = 0; ii < count; ii++)
- X {
- X/*
- X * Insert a space for each jump across an integer.
- X * The normalization (count/sum) ensures that if all
- X * letters were equally probable, they would all have value 1.
- X * Since they are not generally equally probable, then 1 is just the average.
- X * Thus the rightmost space in the printout marks where the average is.
- X * Further left spaces separate off blocks of letters that are approximately
- X * twice as probable as the average, three times, etc.
- X */
- X if (ii > 0)
- X {
- X for (jj = 0; jj <
- X (int) (
- X (randomfactor[randomstr[ii - 1]] + (randomripe[randomstr[ii - 1]] / (float) RIPECOUNT))
- X * count / sum) -
- X (int) (
- X (randomfactor[randomstr[ii]] + (randomripe[randomstr[ii]] / (float) RIPECOUNT))
- X * count / sum);
- X jj++)
- X printf (" ");
- X }
- X printf ("%c", (char) randomstr[ii]);
- X }
- X printf ("\n");
- X }
- X
- X /*
- X * So you don't get penalized for being "slow" after this.
- X */
- X if (charbychar)
- X slowpoke = SLOWPOKEMAX + 1;
- X
- X fflush (stdout);
- X}
- X
- Xint
- Xrancomp (elem1, elem2)
- X int *elem1, *elem2;
- X{
- Xfloat a, b;
- X
- X a = (randomfactor[(*elem1)] + (randomripe[(*elem1)] / (float) RIPECOUNT));
- X b = (randomfactor[(*elem2)] + (randomripe[(*elem2)] / (float) RIPECOUNT));
- X
- X if (a == b)
- X return 0;
- X else if (a > b)
- X return -1;
- X else
- X return 1;
- X}
- END_OF_FILE
- if test 43613 -ne `wc -c <'morse.c'`; then
- echo shar: \"'morse.c'\" unpacked with wrong size!
- fi
- # end of 'morse.c'
- fi
- echo shar: End of shell archive.
- exit 0
-